89

I came upon a struct (called ngx_http_variable_value_t) in my GDB (debugger) session and I would like to print what fields it has in the console.

Is that possible?

Raedwald
  • 46,613
  • 43
  • 151
  • 237
prismofeverything
  • 8,799
  • 8
  • 38
  • 53

9 Answers9

161

You can use the GDB command ptype to print out the definition of a struct or class.

Additionally, use ptype /o to print offsets and sizes of all fields in a struct (like pahole).

Yirkha
  • 12,737
  • 5
  • 38
  • 53
Nate
  • 6,779
  • 8
  • 28
  • 21
  • 6
    This is the right answer. e.g. "(gdb) ptype tm" "type = struct tm { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; long tm_gmtoff; const char *tm_zone; } " – gaoithe Feb 19 '16 at 12:30
  • 5
    What about offsets? – Conrad Meyer Jun 02 '16 at 23:17
  • 4
    @ConradMeyer I use this for offsets: `(gdb) p &((struct foo *)0)->member`. Would be nice to have something non-hacky. – domen Apr 26 '17 at 11:34
  • @domen Yeah, that is my hack too. Also looking for something non-hacky and quicker to type :-). – Conrad Meyer Apr 28 '17 at 15:44
  • What about inner structs? Apparently gdb is not showing them. – jaques-sam Aug 10 '17 at 12:36
  • 5
    @ConradMeyer Put `macro define offsetof(t, f) &((t *) 0)->f)` into `~/.gdbinit`. Then you can use `(gdb) p offsetof(struct foo, member)`. – domen Aug 25 '17 at 09:37
  • Is there a way to also show fields "inherited" from base classes? I.e. basically all fields/offsets accessible from the given pointer. – Dan M. Apr 04 '22 at 17:44
68

If you have debugging symbols built in, you should just be able to print the value: print variable or print *variable if it's a pointer to a struct.

Left For Archive
  • 2,626
  • 1
  • 18
  • 19
  • 6
    And if the variable is a generic pointer, such as a void*, you can cast it to the necessary type, `print ((MY_STRUCT *)variable)`, or to get a specific element of the structure `print ((MY_STRUCT *)variable->my_structure_element`. – Phil DD Oct 18 '13 at 21:49
27

set print pretty on

This option also gives newlines and indentation for p *my_struct_pointer.

Which do you prefer:

$2 = {path = {mnt = 0xffff8800070ce1a0, dentry = 0xffff880006850600},last = {{{hash = 3537271320, len = 2}, hash_len = 12127205912}, name = 0xffff88000659501c "../b.out"}

or:

$3 = {
  path = {
    mnt = 0xffff8800070ce1a0, 
    dentry = 0xffff880006850600
  }, 
  last = {
    {
      {
        hash = 3537271320, 
        len = 2
      }, 
      hash_len = 12127205912
    }, 
    name = 0xffff88000659501c "../b.out"
  },
}
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
8

In addition to using the command line option, you can also use graphical debuggers. I suggest gdbgui, but there are quite a few out there.

screenshot

Disclaimer: I am the developer of gdbgui

cs01
  • 5,287
  • 1
  • 29
  • 28
  • What mi commands are you using to get this information from gdb? – sinan Feb 08 '19 at 08:59
  • If you are running gdbgui, you can view all the commands being sent to gdb on behalf of gdbgui. To do this, go to Settings (gear icon) and check the box that says "Print all sent commands in console, including those sent automatically by gdbgui". Otherwise you can inspect the source code https://github.com/cs01/gdbgui. – cs01 Feb 08 '19 at 17:10
4
  p *((struct my_struct*) variable)

This will help you to print the details of struct in gdb

2

I've only done this through graphic front ends for gdb. Found this entry in gdb online docs. Hope it helps. I believe this will require that the code was created with debugging info included.

ptype [arg] ptype accepts the same arguments as whatis, but prints a detailed description of the type, instead of just the name of the type.

Debugging with GDB:Symbols

2

I would have a look at the Data Display Debugger.

gnud
  • 77,584
  • 5
  • 64
  • 78
0

Assume yout variable is in address X. You can do the following:

set $i1 = (ngx_http_variable_value_t *) = X
print *$i1
print *$i1->name_field

Here an example assuming this is my struct and a variable of type strcut internet has been defined within the address 0x804a008:

struct internet {
  int priority;
  char *name;
};

(gdb) set $i1 = (struct internet *)0x804a008
(gdb) print *$i1
$17 = {priority = 1, name = 0x804a018 "AAAABBBBCCCCDDDDEEEEt\227\004\b"}
(gdb) print $i1->name
$18 = 0x804a018 "AAAABBBBCCCCDDDDEEEEt\227\004\b"
(gdb) print $i1->priority
$19 = 1
(gdb)
0

convert NULL to your type pointer, then use ptype.

(gdb) ptype *(struct iovec*)0
    type = struct iovec {
        void *iov_base;
        size_t iov_len;
    }

or just

ptype {struct iovec}0
kingkong
  • 119
  • 8