whatis用于快速查看变量基础类型(如type = int),不展开结构体或typedef别名;ptype则展开完整类型定义,含结构体成员、数组维度等,支持解引用和/r选项显示原始类型。

用 whatis 快速看变量基础类型
直接输入 whatis 变量名,GDB 会返回最简类型的声明,比如 type = int 或 type = struct child *。它不展开结构体成员,也不显示 typedef 别名的真实类型,适合快速确认是基本类型、指针还是结构体指针。
常见误区:对局部变量执行 whatis 失败,往往是因为调试信息未启用(编译时没加 -g)或变量已被优化掉(加 -O0 重编译)。另外,whatis 对宏、内联函数参数、寄存器名无效。
用 ptype 查看完整类型定义(含结构体成员)
ptype 是真正能“看清”复杂类型的命令。它会展开结构体、联合体、枚举的全部字段,包括数组维度、位域、嵌套类型,甚至显示 typedef 的原始类型(加 /r 选项)。
典型用法:
-
ptype stu→ 显示struct Student { char name[32]; int age; } -
ptype *pstu→ 先解引用再查类型,等价于ptype stu -
ptype /o struct child→ 同时打印每个字段的内存偏移和大小
注意:ptype 不支持局部作用域外的匿名类型(如函数内定义的 unnamed struct),也查不到未被引用的 static 局部变量——它们在符号表中可能根本没生成调试条目。
查不到变量?先确认它是否在当前作用域可见
GDB 的 whatis 和 ptype 都依赖 DWARF 调试信息,且只对当前栈帧中“活跃”的变量有效。如果报错 No symbol "xxx" in current context,可能是以下情况:
- 变量是纯局部非 static 变量,但程序已跳出该函数(栈帧销毁)
- 变量名被优化掉(即使加了
-g,-O2以上仍可能丢符号) - 变量在内联函数中,而你停在的是调用方函数 —— 尝试
frame N切到对应栈帧再试 - 跨文件同名变量冲突,需显式指定作用域:
ptype 'file.c'::var或ptype 'func'::var
用 info variables ^var$ 可列出所有完全匹配的变量及其定义文件,但注意它不显示局部变量。
ptype 和 whatis 的输出差异直接影响调试判断
比如一个指针 char *s:
-
whatis s返回type = char *—— 你知道它是字符指针,但不知道它指向的是单个字节、字符串还是数组 -
ptype s也是type = char *—— 没更多线索 -
ptype *s才返回type = char,配合x/s &s或p (char[32])s才能确认实际用途
真正容易被忽略的是:类型信息本身不包含运行时语义。ptype 告诉你“它被声明为什么”,但不告诉你“它现在指向什么”。要验证指针有效性、字符串是否以 \0 结尾、数组长度是否越界,必须配合 x 或 print 实际读内存。











