【问题标题】:gdb: show typeinfo of some datagdb:显示一些数据的类型信息
【发布时间】:2012-03-23 00:23:53
【问题描述】:

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

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

【问题讨论】:

标签: c++ gdb typeid typeinfo


【解决方案1】:

使用ptype 命令,像这样:

(gdb) ptype 42
type = int

【讨论】:

  • 这会返回type = unsigned short 之类的东西,但我希望它返回type = uint16_t,这样我才能真正知道检查内存时它有多少字节。有没有办法做到这一点?我能想到的最好的办法是做print &my_var,它打印(uint16_t *) 0x7ffffffefc2c,从而显示它的指针类型是uint16_t*,这意味着它的类型是uint16_t
  • 我将此作为答案提出,但如果您有更好的方法来做到这一点,我会全力以赴:stackoverflow.com/a/63404160/4561887
【解决方案2】:

ptype [ARG] 命令将打印类型。

【讨论】:

  • 至少在 gdb v7.6.1 中对这个问题没有帮助,因为它只打印静态类型,而不是多态类型。例如,其中“d”是从基类“B”派生的“D”类型的对象,然后是B* b = &d; (gdb) ptype b type = class B {
  • [在“设置打印对象”的情况下,它的前缀是type = /* real type = D * */,但“whatis”也是如此]
【解决方案3】:

这个问题可能相关:vtable in polymorphic class of C++ using gdb:

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

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

【讨论】:

    【解决方案4】:

    使用ptypewhatisexplore(我的最爱!):

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

    uint32_t value = 1234;
    

    ...以下所有工作:

    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
      

    例子:

    (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
    

    感谢@o11c's comment below 指出whatis 命令的存在。

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

    自己试试吧:

    # 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
    

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

    # 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  
    

    完整的示例命令和输出:

    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) 
    

    我的旧/原始答案

    作为@Star Brilliant says here,这个:

    ptype my_var
    

    返回type = unsigned short 之类的东西,但我希望它返回type = uint16_t,这样我才能真正知道检查内存时它有多少字节。我能想到的最好的方法是:

    print &my_var
    

    它打印(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
    

    同样,注意ptype my_var 显示它是unsigned short,而print &amp;my_var 显示更详细和期望的答案是它是uint16_t

    参考资料:

    1. @o11c's comment below
    2. @Star Brilliant's answer
    3. help all - 我在运行 gdb 时使用了此命令,将输出全部复制粘贴到文本编辑器,然后搜索“类型”以发现 explore 命令。

    另见:

    1. [我的答案]"gdb" debugger skips a break point weirdly
    2. [我的问答]What's the difference between a compiler's `-O0` option and `-Og` option?
    3. [我的问答]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 是一个东西。
    • @o11c,谢谢!事实证明explore 也是一个非常好的命令。我刚刚大量更新了我的答案。
    猜你喜欢
    • 2018-09-29
    • 2018-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 2020-12-16
    • 1970-01-01
    • 2023-03-27
    相关资源
    最近更新 更多