From: Pedro Alves Date: Thu, 14 Nov 2013 19:43:26 +0000 (+0000) Subject: infrun.c:handle_inferior_event: Rework random signal checks. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=bac7d97b66867e7654a1c27b00e7164e24243da0;p=binutils-gdb.git infrun.c:handle_inferior_event: Rework random signal checks. 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-11-14 Pedro Alves * breakpoint.c (bpstat_explains_signal) : 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 48a57d86334..bb09ebe90d1 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2013-11-14 Pedro Alves + + * breakpoint.c (bpstat_explains_signal) : + 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. + 2013-11-14 Pedro Alves * infrun.c (struct execution_control_state): Remove diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 5bfed9d14ec..e8ea0c30a0d 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -4238,7 +4238,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; } @@ -10779,7 +10779,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. */ @@ -12890,7 +12890,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 f37d881857c..8eb2ddd5251 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. */