aboutsummaryrefslogtreecommitdiff
path: root/gdb/doc
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2014-10-27 20:24:59 +0000
committerPedro Alves <palves@redhat.com>2014-10-27 20:26:12 +0000
commite5f8a7cc2d376c81749b6e4a4efc034201cf683c (patch)
treedde215ef253ca851fe7fa3ee9e2d849a1e211b06 /gdb/doc
parentbf67003b4567600ed3022a439207ac8f26454f91 (diff)
downloadgdb-e5f8a7cc2d376c81749b6e4a4efc034201cf683c.zip
gdb-e5f8a7cc2d376c81749b6e4a4efc034201cf683c.tar.gz
gdb-e5f8a7cc2d376c81749b6e4a4efc034201cf683c.tar.bz2
stepi/nexti: skip signal handler if "handle nostop" signal arrives
I noticed that "si" behaves differently when a "handle nostop" signal arrives while the step is in progress, depending on whether the program was stopped at a breakpoint when "si" was entered. Specifically, in case GDB needs to step off a breakpoint, the handler is skipped and the program stops in the next "mainline" instruction. Otherwise, the "si" stops in the first instruction of the signal handler. I was surprised the testsuite doesn't catch this difference. Turns out gdb.base/sigstep.exp covers a bunch of cases related to stepping and signal handlers, but does not test stepi nor nexti, only step/next/continue. My first reaction was that stopping in the signal handler was the correct thing to do, as it's where the next user-visible instruction that is executed is. I considered then "nexti" -- a signal handler could be reasonably considered a subroutine call to step over, it'd seem intuitive to me that "nexti" would skip it. But then, I realized that signals that arrive while a plain/line "step" is in progress _also_ have their handler skipped. A user might well be excused for being confused by this, given: (gdb) help step Step program until it reaches a different source line. And the signal handler's sources will be in different source lines, after all. I think that having to explain that "stepi" steps into handlers, (and that "nexti" wouldn't according to my reasoning above), while "step" does not, is a sign of an awkward interface. E.g., if a user truly is interested in stepping into signal handlers, then it's odd that she has to either force the signal to "handle stop", or recall to do "stepi" whenever such a signal might be delivered. For that use case, it'd seem nicer to me if "step" also stepped into handlers. This suggests to me that we either need a global "step-into-handlers" setting, or perhaps better, make "handle pass/nopass stop/nostop print/noprint" have have an additional axis - "handle stepinto/nostepinto", so that the user could configure whether handlers for specific signals should be stepped into. In any case, I think it's simpler (and thus better) for all step commands to behave the same. This commit thus makes "si/ni" skip handlers for "handle nostop" signals that arrive while the command was already in progress, like step/next do. To be clear, nothing changes if the program was stopped for a signal, and the user enters a stepping command _then_ -- GDB still steps into the handler. The change concerns signals that don't cause a stop and that arrive while the step is in progress. Tested on x86_64 Fedora 20, native and gdbserver. gdb/ 2014-10-27 Pedro Alves <palves@redhat.com> * infrun.c (handle_signal_stop): Also skip handlers when a random signal arrives while handling a "stepi" or a "nexti". Set the thread's 'step_after_step_resume_breakpoint' flag. gdb/doc/ 2014-10-27 Pedro Alves <palves@redhat.com> * gdb.texinfo (Continuing and Stepping): Add cross reference to info on stepping and signal handlers. (Signals): Explain stepping and signal handlers. Add context index entry, and cross references. gdb/testsuite/ 2014-10-27 Pedro Alves <palves@redhat.com> * gdb.base/sigstep.c (dummy): New global. (main): Issue a couple writes to the new global. * gdb.base/sigstep.exp (get_next_pc, test_skip_handler): New procedures. (skip_over_handler): Use test_skip_handler. (top level): Call skip_over_handler for stepi and nexti too. (breakpoint_over_handler): Use test_skip_handler. (top level): Call breakpoint_over_handler for stepi and nexti too.
Diffstat (limited to 'gdb/doc')
-rw-r--r--gdb/doc/ChangeLog7
-rw-r--r--gdb/doc/gdb.texinfo67
2 files changed, 73 insertions, 1 deletions
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index f1b2329..f60fd8f 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,10 @@
+2014-10-27 Pedro Alves <palves@redhat.com>
+
+ * gdb.texinfo (Continuing and Stepping): Add cross reference to
+ info on stepping and signal handlers.
+ (Signals): Explain stepping and signal handlers. Add context
+ index entry, and cross references.
+
2014-10-20 Simon Marchi <simon.marchi@ericsson.com>
* python.texi (Breakpoints In Python): Add parenthesis after
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index a1b8ac7..15c2908 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -5079,7 +5079,9 @@ line of source code, or one machine instruction (depending on what
particular command you use). Either when continuing or when stepping,
your program may stop even sooner, due to a breakpoint or a signal. (If
it stops due to a signal, you may want to use @code{handle}, or use
-@samp{signal 0} to resume execution. @xref{Signals, ,Signals}.)
+@samp{signal 0} to resume execution (@pxref{Signals, ,Signals}),
+or you may step into the signal's handler (@pxref{stepping and signal
+handlers}).)
@table @code
@kindex continue
@@ -5573,6 +5575,66 @@ a result of the fatal signal once it saw the signal. To prevent this,
you can continue with @samp{signal 0}. @xref{Signaling, ,Giving your
Program a Signal}.
+@cindex stepping and signal handlers
+@anchor{stepping and signal handlers}
+
+@value{GDBN} optimizes for stepping the mainline code. If a signal
+that has @code{handle nostop} and @code{handle pass} set arrives while
+a stepping command (e.g., @code{stepi}, @code{step}, @code{next}) is
+in progress, @value{GDBN} lets the signal handler run and then resumes
+stepping the mainline code once the signal handler returns. In other
+words, @value{GDBN} steps over the signal handler. This prevents
+signals that you've specified as not interesting (with @code{handle
+nostop}) from changing the focus of debugging unexpectedly. Note that
+the signal handler itself may still hit a breakpoint, stop for another
+signal that has @code{handle stop} in effect, or for any other event
+that normally results in stopping the stepping command sooner. Also
+note that @value{GDBN} still informs you that the program received a
+signal if @code{handle print} is set.
+
+@anchor{stepping into signal handlers}
+
+If you set @code{handle pass} for a signal, and your program sets up a
+handler for it, then issuing a stepping command, such as @code{step}
+or @code{stepi}, when your program is stopped due to the signal will
+step @emph{into} the signal handler (if the target supports that).
+
+Likewise, if you use the @code{queue-signal} command to queue a signal
+to be delivered to the current thread when execution of the thread
+resumes (@pxref{Signaling, ,Giving your Program a Signal}), then a
+stepping command will step into the signal handler.
+
+Here's an example, using @code{stepi} to step to the first instruction
+of @code{SIGUSR1}'s handler:
+
+@smallexample
+(@value{GDBP}) handle SIGUSR1
+Signal Stop Print Pass to program Description
+SIGUSR1 Yes Yes Yes User defined signal 1
+(@value{GDBP}) c
+Continuing.
+
+Program received signal SIGUSR1, User defined signal 1.
+main () sigusr1.c:28
+28 p = 0;
+(@value{GDBP}) si
+sigusr1_handler () at sigusr1.c:9
+9 @{
+@end smallexample
+
+The same, but using @code{queue-signal} instead of waiting for the
+program to receive the signal first:
+
+@smallexample
+(@value{GDBP}) n
+28 p = 0;
+(@value{GDBP}) queue-signal SIGUSR1
+(@value{GDBP}) si
+sigusr1_handler () at sigusr1.c:9
+9 @{
+(@value{GDBP})
+@end smallexample
+
@cindex extra signal information
@anchor{extra signal information}
@@ -16654,6 +16716,9 @@ be used to pass a signal whose handling state has been set to @code{nopass}
@end table
@c @end group
+@xref{stepping into signal handlers}, for information on how stepping
+commands behave when the thread has a signal queued.
+
@node Returning
@section Returning from a Function