gdb: show typeinfo of some data

Basically, I want to get typeid(*this).name(), i.e. the real type of this.

I want to get this in GDB (without modifying the source code). I tried print typeid(*this) but it says that typeid is unknown (because I didn't included it there in the source file).


Solution 1:

Use ptype command, like this:

(gdb) ptype 42
type = int

Solution 2:

The ptype [ARG] command will print the type.

Solution 3:

This question may be related: vtable in polymorphic class of C++ using gdb:

(gdb) help set print object
Set printing of object's derived type based on vtable info. 

It's not exactly typeid() but it should show the real object type when inspecting a polymorphic pointer (e.g. this in a base class). Naturally works only for classes with a vtable (i.e. at least one virtual method) but so does typeid.

Solution 4:

Use ptype, whatis, and explore (my favorite!):

Where you have a variable named value which is defined as:

uint32_t value = 1234;

...the following all work:

  1. ptype value shows unsigned int
  2. whatis value shows uint32_t
  3. explore value (my favorite!) shows:
    The value of 'value' is of type 'uint32_t' which is a typedef of type 'unsigned int'
    'value' is a scalar value of type 'unsigned int'.
    value = 1234
    

Example:

(gdb) ptype value
type = unsigned int
(gdb) ptype &value
type = unsigned int *
(gdb) whatis value
type = uint32_t
(gdb) explore value
The value of 'value' is of type 'uint32_t' which is a typedef of type 'unsigned int'
'value' is a scalar value of type 'unsigned int'.
value = 1234

Thanks to @o11c's comment below for pointing out the existence of the whatis command.

I discovered the explore command by running help all inside gdb. See my comment in the "References" section below.

Try it yourself:

# download the file "type_punning.c"
wget https://raw.githubusercontent.com/Generalsimus/eRCaGuy_hello_world/master/c/type_punning.c

# build it with optimization OFF (`-O0`) and debugging symbols ON (`-ggdb`), 
# and output all intermediary files (`-save-temps=obj`), and run it in the 
# gdb debugger (`gdb bin/type_punning`)
mkdir -p bin && gcc -Wall -Wextra -Werror -O0 -ggdb -std=c11 -save-temps=obj \
type_punning.c -o bin/type_punning && gdb bin/type_punning

Now, with gdb running, do the following:

# set breakpoint to a line just after `u.value = 1234;`
b type_punning.c:52
# run to that point
r
# Now run these various commands to see what type `u.value` is:
ptype u.value
whatis u.value 
explore u.value  

Full example commands and output:

eRCaGuy_hello_world/c$ mkdir -p bin && gcc -Wall -Wextra -Werror -O0 -ggdb -std=c11 -save-temps=obj type_punning.c -o bin/type_punning && gdb bin/type_punning
GNU gdb (Ubuntu 8.1.1-0ubuntu1) 8.1.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from bin/type_punning...done.
(gdb) b type_punning.c:52
Breakpoint 1 at 0x70b: file type_punning.c, line 52.
(gdb) r
Starting program: /home/gabriel/GS/dev/eRCaGuy_hello_world/c/bin/type_punning 
Type punning and ptr-based serialization demo
TECHNIQUE 1: union-based type punning:

Breakpoint 1, main () at type_punning.c:53
53          printf("1st byte = 0x%02X\n", (u.bytes)[0]);
(gdb) ptype u.value
type = unsigned int
(gdb) whatis u.value 
type = uint32_t
(gdb) explore u.value  
The value of 'u.value' is of type 'uint32_t' which is a typedef of type 'unsigned int'
'u.value' is a scalar value of type 'unsigned int'.
u.value = 1234
(gdb) 

My old/original answer

As @Star Brilliant says here, this:

ptype my_var

returns things like type = unsigned short, but I want it to return type = uint16_t instead, so I can truly know how many bytes it is when inspecting memory. The best I can figure out to get this effect is to do:

print &my_var

which prints (uint16_t *) 0x7ffffffefc2c, thereby revealing that its pointer type is uint16_t*, meaning its type is uint16_t.

I find this to be more-useful than ptype my_var, but a more direct way to get this effect is desired in case you have any suggestions.

Sample gdb commands and output:

(gdb) ptype my_var
type = unsigned short
(gdb) print &my_var
$27 = (uint16_t *) 0x7ffffffefc2c

Again, notice ptype my_var reveals it is an unsigned short, whereas print &my_var reveals the more-detailed and desired answer which is that it is a uint16_t.

References:

  1. @o11c's comment below
  2. @Star Brilliant's answer
  3. help all - I used this command while running gdb, copy-pasted the output all to a text editor, and searched for "type" to discover the explore command.

See also:

  1. [my ans.] "gdb" debugger skips a break point weirdly
  2. [my Q&A] What's the difference between a compiler's `-O0` option and `-Og` option?
  3. [my Q&A] https://askubuntu.com/questions/1349047/where-do-i-find-core-dump-files-and-how-do-i-view-and-analyze-the-backtrace-st

Keywords: how to run gdb; how to view variable types and values in gdb; how to build and compile for gdb debugging symbols