Search code examples
gdb

Understanding sigaction structure using GDB


I want to better understand sigaction and I have reached this instruction using gdb.

0x73xxxxxxxx: bl 0x73xxxxxxxx <sigaction@plt>

If I were to explore its parameters,

x0             0x0e                14
x1             0x7fxxxxxxxx        xxxxxxxxxxxx
x2             0x0
  • x0 should be referring to the signal to handle?
  • x1 should be the new sigaction structure?
  • x2 should be the old sigaction structure (so this means there is no old sigaction structure defined?)

If I explore x1 further,

(gdb) x/16gx 0x7fxxxxxxxx
0x7fe5xxxxc0:   0x0000000000000004  0x0000007365xxxxxx
0x7fe5xxxxd0:   0xffffffffffffffff  0x0000000000000000
0x7fe5xxxxe0:   0x0000000000000020  0x0000003800030015
0x7fe5xxxxf0:   0x0000003800020015  0x0000003800010015
0x7fe5xxxx00:   0x000000380f000015  0x0000000c00000020
0x7fe5xxxx10:   0x0000007300020015  0x0000007304000025
0x7fe5xxxx20:   0x000000730b030025  0x0000000800000020

What do each of the qword mean? I know the second qword (0x7365xxxxxx) should be referring to the handler function for the signal but how do I map the rest of the qwords to the sigaction structure?


Solution

  • how do I map the rest of the qwords to the sigaction structure?

    You look in whatever header defines struct sigaction.

    Using echo "#include <signal.h>" | gcc -xc - -E can help you find that header and the definition.

    On my system, that's /usr/include/x86_64-linux-gnu/bits/sigaction.h and it contains:

    struct sigaction
      {
        union
          {
            __sighandler_t sa_handler;
            void (*sa_sigaction) (int, siginfo_t *, void *);
          }
        __sigaction_handler;
        __sigset_t sa_mask;
        int sa_flags;
        void (*sa_restorer) (void);
      };
    

    But on your system this would be different (perhaps sa_flags are before sa_handler).

    Update:

    Is there a GDB command that lets me cast the memory address to the struct layout for sigaction?

    Yes: you simply cast it like so:

    (gdb) print *(struct sigaction *) 0x7fxxxxxxxx
    

    If GDB doesn't know what struct sigaction is, you can tell it.

    I searched online that sigset_t is 128 bytes large,

    Searching online is the wrong answer. You should just look in the gcc -E output I already mentioned. On my system, __sitset_t is:

    typedef struct
    {
      unsigned long int __val[(1024 / (8 * sizeof (unsigned long int)))];
    } __sigset_t;
    

    That's 1024 / 8 == 128.

    does that mean I have to count 16 by 8 qwords in order to map that to sigset_t?

    Yes.