This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH 4/7] infrun.c:handle_inferior_event: Rework random signal checks.
- From: Pedro Alves <palves at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Thu, 31 Oct 2013 21:32:02 +0000
- Subject: [PATCH 4/7] infrun.c:handle_inferior_event: Rework random signal checks.
- Authentication-results: sourceware.org; auth=none
- References: <1383255125-9977-1-git-send-email-palves at redhat dot com>
Looking at the current random signal checks:
if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP)
random_signal
= !((bpstat_explains_signal (ecs->event_thread->control.stop_bpstat,
GDB_SIGNAL_TRAP)
!= BPSTAT_SIGNAL_NO)
|| stopped_by_watchpoint
|| ecs->event_thread->control.trap_expected
|| (ecs->event_thread->control.step_range_end
&& (ecs->event_thread->control.step_resume_breakpoint
== NULL)));
else
{
enum bpstat_signal_value sval;
sval = bpstat_explains_signal (ecs->event_thread->control.stop_bpstat,
ecs->event_thread->suspend.stop_signal);
random_signal = (sval == BPSTAT_SIGNAL_NO);
if (sval == BPSTAT_SIGNAL_HIDE)
ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
}
We can observe:
- the stepping checks bit:
...
|| ecs->event_thread->control.trap_expected
|| (ecs->event_thread->control.step_range_end
&& (ecs->event_thread->control.step_resume_breakpoint
== NULL)));
...
is just like currently_stepping:
static int
currently_stepping (struct thread_info *tp)
{
return ((tp->control.step_range_end
&& tp->control.step_resume_breakpoint == NULL)
|| tp->control.trap_expected
|| bpstat_should_step ());
}
except it misses the bpstat_should_step check (***).
It's not really necessary to check bpstat_should_step in the
random signal tests, because software watchpoints always end up in
the bpstat list anyway, which means bpstat_explains_signal with
GDB_SIGNAL_TRAP always returns at least BPSSTAT_SIGNAL_HIDE, but I
think the code is clearer if we reuse currently_stepping.
*** - bpstat_should_step checks to see if there's any software
watchpoint in the breakpoint list, because we need to force the
target to single-step all the way, to evaluate the watchpoint's
value at each step.
- we never hide GDB_SIGNAL_TRAP, even if the bpstat returns
BPSTAT_SIGNAL_HIDE, which is actually the default for all
breakpoints. If we make the default be BPSTAT_SIGNAL_PASS, then
we can merge the two bpstat_explains_signal paths.
gdb/
2013-10-31 Pedro Alves <palves@redhat.com>
* breakpoint.c (bpstat_explains_signal) <Moribund locations>:
Return BPSTAT_SIGNAL_PASS instead of BPSTAT_SIGNAL_HIDE.
(explains_signal_watchpoint): Return BPSTAT_SIGNAL_PASS instead of
BPSTAT_SIGNAL_HIDE.
(base_breakpoint_explains_signal): Return BPSTAT_SIGNAL_PASS
instead of BPSTAT_SIGNAL_HIDE.
* infrun.c (handle_inferior_event): Rework random signal checks.
---
gdb/breakpoint.c | 6 +++---
gdb/infrun.c | 35 +++++++++++++++--------------------
2 files changed, 18 insertions(+), 23 deletions(-)
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 1782c99..c506fc0 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -4237,7 +4237,7 @@ bpstat_explains_signal (bpstat bsp, enum gdb_signal sig)
/* A moribund location can never explain a signal other than
GDB_SIGNAL_TRAP. */
if (sig == GDB_SIGNAL_TRAP)
- newval = BPSTAT_SIGNAL_HIDE;
+ newval = BPSTAT_SIGNAL_PASS;
else
newval = BPSTAT_SIGNAL_NO;
}
@@ -10771,7 +10771,7 @@ explains_signal_watchpoint (struct breakpoint *b, enum gdb_signal sig)
if (b->type == bp_watchpoint && sig != GDB_SIGNAL_TRAP)
return BPSTAT_SIGNAL_NO;
- return BPSTAT_SIGNAL_HIDE;
+ return BPSTAT_SIGNAL_PASS;
}
/* The breakpoint_ops structure to be used in hardware watchpoints. */
@@ -12882,7 +12882,7 @@ base_breakpoint_decode_linespec (struct breakpoint *b, char **s,
static enum bpstat_signal_value
base_breakpoint_explains_signal (struct breakpoint *b, enum gdb_signal sig)
{
- return BPSTAT_SIGNAL_HIDE;
+ return BPSTAT_SIGNAL_PASS;
}
/* The default "after_condition_true" method. */
diff --git a/gdb/infrun.c b/gdb/infrun.c
index f37d881..8eb2ddd 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -4234,7 +4234,7 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
"infrun: no user watchpoint explains "
"watchpoint SIGTRAP, ignoring\n");
- /* NOTE: cagney/2003-03-29: These two checks for a random signal
+ /* NOTE: cagney/2003-03-29: These checks for a random signal
at one stage in the past included checks for an inferior
function call's call dummy's return breakpoint. The original
comment, that went with the test, read:
@@ -4254,27 +4254,22 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
be necessary for call dummies on a non-executable stack on
SPARC. */
- if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP)
- random_signal
- = !((bpstat_explains_signal (ecs->event_thread->control.stop_bpstat,
- GDB_SIGNAL_TRAP)
- != BPSTAT_SIGNAL_NO)
- || stopped_by_watchpoint
- || ecs->event_thread->control.trap_expected
- || (ecs->event_thread->control.step_range_end
- && (ecs->event_thread->control.step_resume_breakpoint
- == NULL)));
- else
- {
- enum bpstat_signal_value sval;
+ /* See if the breakpoints module can explain the signal. */
+ sval = bpstat_explains_signal (ecs->event_thread->control.stop_bpstat,
+ ecs->event_thread->suspend.stop_signal);
+ random_signal = (sval == BPSTAT_SIGNAL_NO);
+
+ /* If not, perhaps stepping/nexting can. */
+ if (random_signal)
+ random_signal = !(ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
+ && currently_stepping (ecs->event_thread));
- sval = bpstat_explains_signal (ecs->event_thread->control.stop_bpstat,
- ecs->event_thread->suspend.stop_signal);
- random_signal = (sval == BPSTAT_SIGNAL_NO);
+ /* No? Perhaps we got a moribund watchpoint. */
+ if (random_signal)
+ random_signal = !stopped_by_watchpoint;
- if (sval == BPSTAT_SIGNAL_HIDE)
- ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
- }
+ if (sval == BPSTAT_SIGNAL_HIDE)
+ ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
/* For the program's own signals, act according to
the signal handling tables. */
--
1.7.11.7