gdb:显示某些数据的typeinfo

Alb*_*ert 31 c++ gdb typeid typeinfo

基本上,我想得到typeid(*this).name(),即真正的类型this.

我想在GDB中得到它(不修改源代码).我尝试过,print typeid(*this)但它说typeid未知(因为我没有把它包含在源文件中).

Sta*_*ant 41

使用ptype命令,如下所示:

(gdb) ptype 42
type = int
Run Code Online (Sandbox Code Playgroud)


Gab*_*les 29

使用ptypewhatis、 和explore(我最喜欢的!):

其中您有一个名为的变量value,其定义为:

uint32_t value = 1234;
Run Code Online (Sandbox Code Playgroud)

...以下所有工作:

  1. ptype value节目unsigned int
  2. whatis value节目uint32_t
  3. 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
    
    Run Code Online (Sandbox Code Playgroud)

例子:

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
Run Code Online (Sandbox Code Playgroud)

感谢@o11c 下面的评论指出了该whatis命令的存在。

explore通过在 gdb 中运行发现了该命令help all。请参阅下面“参考文献”部分中我的评论。

自己尝试一下:

(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
Run Code Online (Sandbox Code Playgroud)

现在,在gdb运行时执行以下操作:

# 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
Run Code Online (Sandbox Code Playgroud)

完整示例命令和输出:

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) 
Run Code Online (Sandbox Code Playgroud)

我的旧/原始答案

正如@Star Brilliant 在这里所说的那样:

ptype my_var
Run Code Online (Sandbox Code Playgroud)

返回类似 的东西type = unsigned short,但我希望它返回type = uint16_t,这样我在检查内存时可以真正知道它有多少字节。我能想到的要获得这种效果的最好方法是:

print &my_var
Run Code Online (Sandbox Code Playgroud)

它打印(uint16_t *) 0x7ffffffefc2c,从而揭示它的指针类型是uint16_t*,这意味着它的类型是uint16_t

我发现这比 更有用ptype my_var,但是如果您有任何建议,则需要一种更直接的方法来获得此效果。

gdb 命令和输出示例:

(gdb) ptype my_var
type = unsigned short
(gdb) print &my_var
$27 = (uint16_t *) 0x7ffffffefc2c
Run Code Online (Sandbox Code Playgroud)

同样,通知ptype my_var揭示了它是一个unsigned short,而print &my_var揭示了更详细和期望的答案,即它是一个uint16_t

参考:

  1. @o11c 的评论如下
  2. @星耀的回答
  3. help all- 我在运行时使用了此命令gdb,将输出全部复制粘贴到文本编辑器,然后搜索“type”以发现该explore命令。

也可以看看:

  1. 我对如何在 GDB 中查看像数组一样的指针?
  2. 我对如何printf在 GDB 中使用以便围绕变量输出编写自定义描述的回答
  3. [我的回答] “gdb”调试器奇怪地跳过断点
  4. [我的问答]编译器的“-O0”选项和“-Og”选项有什么区别?
  5. [我的问答] https://askubuntu.com/questions/1349047/where-do-i-find-core-dump-files-and-how-do-i-view-and-analyze-the-backtrace-st

关键词:如何运行gdb;如何在gdb中查看变量类型和值;如何构建和编译 gdb 调试符号

  • ‘whatis’是一个东西。 (2认同)

t. *_*man 11

'ptype [ARG]'命令将打印该类型.

  • 至少在gdb v7.6.1中没有帮助解决这个问题,因为它只打印静态类型,而不是多态类型.例如,其中"d"是从基类"B"导出的类型"D"的对象,则"B*b =&d; (gdb)ptype b type = class B {` (2认同)

reg*_*arg 10

这个问题可能是相关的:使用gdb的C++多态类中的vtable:

(gdb) help set print object
Set printing of object's derived type based on vtable info. 
Run Code Online (Sandbox Code Playgroud)

它不完全是typeid(),但它应该在检查多态指针时显示真实的对象类型(例如this在基类中).当然只适用于具有vtable的类(即至少一个虚拟方法),但也适用typeid.