gdb: Signals

 
 5.4 Signals
 ===========
 
 A signal is an asynchronous event that can happen in a program.  The
 operating system defines the possible kinds of signals, and gives each
 kind a name and a number.  For example, in Unix 'SIGINT' is the signal a
 program gets when you type an interrupt character (often 'Ctrl-c');
 'SIGSEGV' is the signal a program gets from referencing a place in
 memory far away from all the areas in use; 'SIGALRM' occurs when the
 alarm clock timer goes off (which happens only if your program has
 requested an alarm).
 
    Some signals, including 'SIGALRM', are a normal part of the
 functioning of your program.  Others, such as 'SIGSEGV', indicate
 errors; these signals are "fatal" (they kill your program immediately)
 if the program has not specified in advance some other way to handle the
 signal.  'SIGINT' does not indicate an error in your program, but it is
 normally fatal so it can carry out the purpose of the interrupt: to kill
 the program.
 
    GDB has the ability to detect any occurrence of a signal in your
 program.  You can tell GDB in advance what to do for each kind of
 signal.
 
    Normally, GDB is set up to let the non-erroneous signals like
 'SIGALRM' be silently passed to your program (so as not to interfere
 with their role in the program's functioning) but to stop your program
 immediately whenever an error signal happens.  You can change these
 settings with the 'handle' command.
 
 'info signals'
 'info handle'
      Print a table of all the kinds of signals and how GDB has been told
      to handle each one.  You can use this to see the signal numbers of
      all the defined types of signals.
 
 'info signals SIG'
      Similar, but print information only about the specified signal
      number.
 
      'info handle' is an alias for 'info signals'.
 
 'catch signal [SIGNAL... | 'all']'
      Set a catchpoint for the indicated signals.  SeeSet
      Catchpoints, for details about this command.
 
 'handle SIGNAL [KEYWORDS...]'
      Change the way GDB handles signal SIGNAL.  The SIGNAL can be the
      number of a signal or its name (with or without the 'SIG' at the
      beginning); a list of signal numbers of the form 'LOW-HIGH'; or the
      word 'all', meaning all the known signals.  Optional arguments
      KEYWORDS, described below, say what change to make.
 
    The keywords allowed by the 'handle' command can be abbreviated.
 Their full names are:
 
 'nostop'
      GDB should not stop your program when this signal happens.  It may
      still print a message telling you that the signal has come in.
 
 'stop'
      GDB should stop your program when this signal happens.  This
      implies the 'print' keyword as well.
 
 'print'
      GDB should print a message when this signal happens.
 
 'noprint'
      GDB should not mention the occurrence of the signal at all.  This
      implies the 'nostop' keyword as well.
 
 'pass'
 'noignore'
      GDB should allow your program to see this signal; your program can
      handle the signal, or else it may terminate if the signal is fatal
      and not handled.  'pass' and 'noignore' are synonyms.
 
 'nopass'
 'ignore'
      GDB should not allow your program to see this signal.  'nopass' and
      'ignore' are synonyms.
 
    When a signal stops your program, the signal is not visible to the
 program until you continue.  Your program sees the signal then, if
 'pass' is in effect for the signal in question _at that time_.  In other
 words, after GDB reports a signal, you can use the 'handle' command with
 'pass' or 'nopass' to control whether your program sees that signal when
 you continue.
 
    The default is set to 'nostop', 'noprint', 'pass' for non-erroneous
 signals such as 'SIGALRM', 'SIGWINCH' and 'SIGCHLD', and to 'stop',
 'print', 'pass' for the erroneous signals.
 
    You can also use the 'signal' command to prevent your program from
 seeing a signal, or cause it to see a signal it normally would not see,
 or to give it any signal at any time.  For example, if your program
 stopped due to some sort of memory reference error, you might store
 correct values into the erroneous variables and continue, hoping to see
 more execution; but your program would probably terminate immediately as
 a result of the fatal signal once it saw the signal.  To prevent this,
 you can continue with 'signal 0'.  SeeGiving your Program a Signal
 Signaling.
 
    GDB optimizes for stepping the mainline code.  If a signal that has
 'handle nostop' and 'handle pass' set arrives while a stepping command
 (e.g., 'stepi', 'step', 'next') is in progress, GDB lets the signal
 handler run and then resumes stepping the mainline code once the signal
 handler returns.  In other words, GDB steps over the signal handler.
 This prevents signals that you've specified as not interesting (with
 '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 'handle stop' in effect, or for any other event
 that normally results in stopping the stepping command sooner.  Also
 note that GDB still informs you that the program received a signal if
 'handle print' is set.
 
    If you set 'handle pass' for a signal, and your program sets up a
 handler for it, then issuing a stepping command, such as 'step' or
 'stepi', when your program is stopped due to the signal will step _into_
 the signal handler (if the target supports that).
 
    Likewise, if you use the 'queue-signal' command to queue a signal to
 be delivered to the current thread when execution of the thread resumes
 (SeeGiving your Program a Signal Signaling.), then a stepping
 command will step into the signal handler.
 
    Here's an example, using 'stepi' to step to the first instruction of
 'SIGUSR1''s handler:
 
      (gdb) handle SIGUSR1
      Signal        Stop      Print   Pass to program Description
      SIGUSR1       Yes       Yes     Yes             User defined signal 1
      (gdb) c
      Continuing.
 
      Program received signal SIGUSR1, User defined signal 1.
      main () sigusr1.c:28
      28        p = 0;
      (gdb) si
      sigusr1_handler () at sigusr1.c:9
      9       {
 
    The same, but using 'queue-signal' instead of waiting for the program
 to receive the signal first:
 
      (gdb) n
      28        p = 0;
      (gdb) queue-signal SIGUSR1
      (gdb) si
      sigusr1_handler () at sigusr1.c:9
      9       {
      (gdb)
 
    On some targets, GDB can inspect extra signal information associated
 with the intercepted signal, before it is actually delivered to the
 program being debugged.  This information is exported by the convenience
 variable '$_siginfo', and consists of data that is passed by the kernel
 to the signal handler at the time of the receipt of a signal.  The data
 type of the information itself is target dependent.  You can see the
 data type using the 'ptype $_siginfo' command.  On Unix systems, it
 typically corresponds to the standard 'siginfo_t' type, as defined in
 the 'signal.h' system header.
 
    Here's an example, on a GNU/Linux system, printing the stray
 referenced address that raised a segmentation fault.
 
      (gdb) continue
      Program received signal SIGSEGV, Segmentation fault.
      0x0000000000400766 in main ()
      69        *(int *)p = 0;
      (gdb) ptype $_siginfo
      type = struct {
          int si_signo;
          int si_errno;
          int si_code;
          union {
              int _pad[28];
              struct {...} _kill;
              struct {...} _timer;
              struct {...} _rt;
              struct {...} _sigchld;
              struct {...} _sigfault;
              struct {...} _sigpoll;
          } _sifields;
      }
      (gdb) ptype $_siginfo._sifields._sigfault
      type = struct {
          void *si_addr;
      }
      (gdb) p $_siginfo._sifields._sigfault.si_addr
      $1 = (void *) 0x7ffff7ff7000
 
    Depending on target support, '$_siginfo' may also be writable.
 
    On some targets, a 'SIGSEGV' can be caused by a boundary violation,
 i.e., accessing an address outside of the allowed range.  In those cases
 GDB may displays additional information, depending on how GDB has been
 told to handle the signal.  With 'handle stop SIGSEGV', GDB displays the
 violation kind: "Upper" or "Lower", the memory address accessed and the
 bounds, while with 'handle nostop SIGSEGV' no additional information is
 displayed.
 
    The usual output of a segfault is:
      Program received signal SIGSEGV, Segmentation fault
      0x0000000000400d7c in upper () at i386-mpx-sigsegv.c:68
      68        value = *(p + len);
 
    While a bound violation is presented as:
      Program received signal SIGSEGV, Segmentation fault
      Upper bound violation while accessing address 0x7fffffffc3b3
      Bounds: [lower = 0x7fffffffc390, upper = 0x7fffffffc3a3]
      0x0000000000400d7c in upper () at i386-mpx-sigsegv.c:68
      68        value = *(p + len);