gdb: show typeinfo of some data
Asked Answered
M

4

77

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).

Mervin answered 5/3, 2012 at 14:21 Comment(5)
gdb doesn't support typeid.Ectoblast
same problem nowadays with lldb...Bomke
Possible duplicate of How to determine whether an object is an instance of certain C++ class in GDBIbby
If anybody came here trying to "show type of a given variable", whatis command is your friend.Adey
ptype, whatis, and explore (my favorite) all work, although they are all a little different. I've written about them here.Naturism
B
84

Use ptype command, like this:

(gdb) ptype 42
type = int
Bung answered 18/6, 2015 at 16:37 Comment(2)
This 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. Is there any way to do that? The best I can figure out 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.Naturism
I presented this as an answer, but if you have a better way to do this I'm all ears: https://mcmap.net/q/225918/-gdb-show-typeinfo-of-some-data.Naturism
N
32

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 answer on How to view a pointer like an array in GDB?
  2. My answer on How to use printf in GDB in order to write a custom description around your variable output
  3. [my ans.] "gdb" debugger skips a break point weirdly
  4. [my Q&A] What's the difference between a compiler's `-O0` option and `-Og` option?
  5. [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

Naturism answered 13/8, 2020 at 22:41 Comment(5)
whatis is a thing.Mentalist
@o11c, thanks! It turns out explore is a really nice command too. I've just massively updated my answer.Naturism
while in TUI mode (split screen with source code; tui enable), when I executed explore somevariable, the gdb prompt showed "... Continue exploring it as a pointer to a single value [y/n]:". But I couldn't enter any answer (y or n). It seems the TUI mode swallowed my answer input. I first had to cancel the explore somevariable command by pressing Ctrl+c Ctrl+d, then disable TUI mode with tui disable. Repeating explore somevariable now allowed me to answer the question.Soutane
@Abdull, I think you just need to press Ctrl + X, then o, to switch focus back from the TUI window to the 'o'ther window where the GDB commands go. I have that command saved in my notes here. Search the doc for Ctrl + X, o.Naturism
Undefined command: "explore" for me in GDB 8.3.1Rood
O
18

The ptype [ARG] command will print the type.

Ophicleide answered 8/1, 2014 at 5:39 Comment(2)
At least in gdb v7.6.1 that doesn't help with this question, as it only prints the static type, not the polymorphic type. For example where "d" is an object of type "D" derived from base class "B" then B* b = &d; (gdb) ptype b type = class B {Watchmaker
[with "set print object on" it gets prefixed with type = /* real type = D * */ but then so does "whatis"]Watchmaker
D
14

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.

Domino answered 26/7, 2012 at 8:14 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.