+ /* Currently, our software single-step implementation leads to different
+ results than hardware single-stepping in one situation: when stepping
+ into delivering a signal which has an associated signal handler,
+ hardware single-step will stop at the first instruction of the handler,
+ while software single-step will simply skip execution of the handler.
+
+ For now, this difference in behavior is accepted since there is no
+ easy way to actually implement single-stepping into a signal handler
+ without kernel support.
+
+ However, there is one scenario where this difference leads to follow-on
+ problems: if we're stepping off a breakpoint by removing all breakpoints
+ and then single-stepping. In this case, the software single-step
+ behavior means that even if there is a *breakpoint* in the signal
+ handler, GDB still would not stop.
+
+ Fortunately, we can at least fix this particular issue. We detect
+ here the case where we are about to deliver a signal while software
+ single-stepping with breakpoints removed. In this situation, we
+ revert the decisions to remove all breakpoints and insert single-
+ step breakpoints, and instead we install a step-resume breakpoint
+ at the current address, deliver the signal without stepping, and
+ once we arrive back at the step-resume breakpoint, actually step
+ over the breakpoint we originally wanted to step over. */
+ if (singlestep_breakpoints_inserted_p
+ && tp->control.trap_expected && sig != TARGET_SIGNAL_0)
+ {
+ /* If we have nested signals or a pending signal is delivered
+ immediately after a handler returns, might might already have
+ a step-resume breakpoint set on the earlier handler. We cannot
+ set another step-resume breakpoint; just continue on until the
+ original breakpoint is hit. */
+ if (tp->control.step_resume_breakpoint == NULL)
+ {
+ insert_hp_step_resume_breakpoint_at_frame (get_current_frame ());
+ tp->step_after_step_resume_breakpoint = 1;
+ }
+
+ remove_single_step_breakpoints ();
+ singlestep_breakpoints_inserted_p = 0;
+
+ insert_breakpoints ();
+ tp->control.trap_expected = 0;
+ }
+