0

I am trying to get things out of the siginfo_t struct. For SIGABRT (=6) I get

(gdb) print signo
$1 = 6

(gdb) print *siginfo
$2 = {si_signo = 0, si_errno = 0, si_code = 1689088, __pad0 = 0, _sifields = {_pad = {1689088, 0, 2097152, 0, 1, 6, 
      -136419500, 32767, -9920, 32767, -134466304, 32767, 2, 0, -136446113, 32767, -134465040, 32767, -136425789, 
      32767, 1, 0, -146454064, 32767, 4367061, 0, 4196947, 0}, _kill = {si_pid = 1689088, si_uid = 0}, _timer = {
      si_tid = 1689088, si_overrun = 0, si_sigval = {sival_int = 2097152, sival_ptr = 0x200000}}, _rt = {
      si_pid = 1689088, si_uid = 0, si_sigval = {sival_int = 2097152, sival_ptr = 0x200000}}, _sigchld = {
      si_pid = 1689088, si_uid = 0, si_status = 2097152, si_utime = 25769803777, si_stime = 140737351935828}, 
    _sigfault = {si_addr = 0x19c600, si_addr_lsb = 0, _bounds = {_addr_bnd = {_lower = 0x600000001, 
          _upper = 0x7ffff7de6754 <_dl_name_match_p+84>}, _pkey = 1}}, _sigpoll = {si_band = 1689088, 
      si_fd = 2097152}, _sigsys = {_call_addr = 0x19c600, _syscall = 2097152, _arch = 0}}}

The signo argument to my signal handler is 6, as expected. But si_signo in the struct appears to have a random value. Similarly, for SIGSEGV = 11:

(gdb) print *siginfo
$1 = {si_signo = 1, si_errno = 0, si_code = -134225552, __pad0 = 32767, _sifields = {_pad = {4196859, 0, 0, 1, 
      -10368, 32767, -10352, 32767, -134224696, 32767, 0, 0, -140162064, 32767, -146519444, 32767, -1, 0, 0, 0, 
      -146481208, 32767, -134465040, 32767, -10112, 32767, 0, 32767}, _kill = {si_pid = 4196859, si_uid = 0}, 
    _timer = {si_tid = 4196859, si_overrun = 0, si_sigval = {sival_int = 0, sival_ptr = 0x100000000}}, _rt = {
      si_pid = 4196859, si_uid = 0, si_sigval = {sival_int = 0, sival_ptr = 0x100000000}}, _sigchld = {
      si_pid = 4196859, si_uid = 0, si_status = 0, si_utime = 140737488344960, si_stime = 140737488344976}, 
    _sigfault = {si_addr = 0x4009fb, si_addr_lsb = 0, _bounds = {_addr_bnd = {_lower = 0x7fffffffd780, 
          _upper = 0x7fffffffd790}, _pkey = 4294956928}}, _sigpoll = {si_band = 4196859, si_fd = 0}, _sigsys = {
      _call_addr = 0x4009fb, _syscall = 0, _arch = 1}}}
(gdb) print signo
$2 = 11

The strange thing is that everything seems fine in valgrind, but not when running the program outside valgrind. Compiler optimization level does not matter.

This is how sigaction is setup:

struct sigaction action;
memset(&action, 0, sizeof(struct sigaction));
sigemptyset(&action.sa_mask);
action.sa_flags = SA_SIGINFO;
action.sa_sigaction = signal_handler;
action.sa_flags = SA_RESETHAND;
sigaction(SIGABRT, &action, nullptr);
sigaction(SIGSEGV, &action, nullptr);
sigaction(SIGBUS, &action, nullptr);
sigaction(SIGILL, &action, nullptr);
sigaction(SIGFPE, &action, nullptr);
user877329
  • 6,717
  • 8
  • 46
  • 88
  • 1
    `action.sa_flags = SA_RESETHAND` will turn off the `SA_SIGINFO` flag that was set two statements before. Without that flag, the siginfo arg is likely garbage (it might be whatever happens to be in the %rdx register when the signal is delivered). – Mark Plotnick Oct 14 '19 at 19:51
  • @MarkPlotnick I am stupid. Or, that is why unions are bad. – user877329 Oct 15 '19 at 15:26

0 Answers0