GDB 符号检视三件套:`ptype` / `info variables` / `info functions`
调试 NuttX/Vela 这类嵌入式系统时光会bt和print远远不够。真正能让你在陌生代码里快速定位、看清结构、批量布点的是 GDB 的符号检视命令。本文整理三件最常用的ptype—— 看类型长什么样info variables—— 找全局/静态变量在哪info functions—— 找函数在哪它们都不打印运行时值而是从符号表里捞元数据速度快、不依赖程序运行状态特别适合 coredump 离线分析。一、ptype—— 查看类型定义ptypeprint type只打印类型的结构不打印变量的值。常见用法命令作用ptype var查看变量的类型定义ptype type直接查看某个类型struct/union/enum/typedefptype/o struct显示 offset 和 size调试内存布局神器ptype/m class只显示成员不展开继承Cptype expr查看任意表达式的类型如ptype foo-bar[2].baz它能干什么看 struct 字段布局(gdb) ptype/o struct task_struct /* offset | size */ type struct task_struct { /* 0 | 8 */ long state; /* 8 | 8 */ void *stack; ...排查内存对齐、padding、字段偏移问题时比offsetof直观得多。typedef 穿透ptype size_t告诉你它实际是unsigned long避免猜类型。enum 取值ptype enum state_e一次性列出所有枚举值。函数签名ptype my_func显示返回值和参数类型特别适合调试函数指针。C 类层次ptype完整展开含虚函数表、继承ptype/m只看自身成员。判断指针 vs 数组源码里int a[10]和int *a看着像ptype一眼分清。与近邻命令对比print x/p x→ 看值ptype x→ 看类型whatis x→ 类型简版不展开 struct 成员一行输出info types regex→ 在符号表里搜类型名排查 crash 看 coredump 时ptype/o配合p *(struct foo *)0xaddr是定位「字段偏移踩错 / 结构体版本不一致」的常用组合。二、info variables—— 查找全局/静态变量info variables从符号表里捞全局和静态变量不打印值只告诉你叫什么、在哪、什么类型。基本用法命令作用info variables列出所有全局和静态变量通常很长info variables regex用正则过滤最常用info variables -n只看非调试符号minimal symbols典型场景找变量定义在哪(gdb) info variables ^g_task_list$ File kernel/sched/task.c: 42: struct list_head g_task_list;直接告诉你文件:行号 类型比翻代码快。模糊搜索忘了变量全名info variables uart.*config一搜就出。看驱动注册了哪些静态结构info variables _ops$找所有以_ops结尾的file_operations、uart_ops之类。核对链接产物某个static变量是否真的进了最终镜像。与近邻命令对比命令看什么info variables re全局/静态变量符号info functions re函数符号info types re类型名struct/typedef/enuminfo address sym单个符号的地址info symbol addr反查这个地址属于哪个符号print var拿到变量地址要先知道名字ptype var看类型定义⚠️局部变量不会出现在info variables里 —— 那是栈上的要用info locals/info args看当前帧。三、info functions—— 查找函数符号info functions与info variables是一对专门搜函数。基本用法命令作用info functions列出所有函数通常爆屏慎用info functions regex正则过滤最常用info functions -n只看非调试符号info functions -q requiet 模式不打印文件分组头info functions -t type re按返回类型过滤较新 GDB典型场景找函数定义在哪(gdb) info functions ^uart_open$ File drivers/serial/uart.c: 128: int uart_open(struct file *filep);直接给文件:行号 完整签名。模糊搜索info functions .*_init$列出所有_init结尾的初始化函数。看某模块对外接口info functions ^uart_列出 uart 子系统所有函数。C 重载/模板所有重载版本一并列出签名各异方便挑你要打断点的那个。静态函数也能找到只要带调试符号不像 grep 还要管作用域。调试组合拳(gdb) info functions probe # 模糊找入口 (gdb) b *uart_probe # 在函数入口下断点 (gdb) info address uart_probe # 拿函数地址用于函数指针比对 (gdb) disas uart_probe # 反汇编 (gdb) ptype uart_probe # 看签名 (gdb) rbreak ^uart_ # 给所有 uart_ 开头函数下断点批量与近邻命令对比命令用途info functions re列出匹配的函数符号rbreak re给匹配的函数批量下断点破坏性会真下断disas func反汇编整个函数体info line func看函数起始行号 → 地址映射ptype func看函数类型签名返回值/参数四、三件套联动crash 离线分析的标准流程假设 coredump 里看到一个陌生符号uart_priv出现在栈上(gdb) info variables ^uart_priv$ # 1. 在哪定义 File drivers/serial/uart.c: 89: static struct uart_priv_s uart_priv; (gdb) ptype uart_priv # 2. 类型长啥样 type struct uart_priv_s { int state; struct circbuf rx; ... } (gdb) ptype/o struct uart_priv_s # 3. 字段偏移确认 /* offset | size */ ... (gdb) p uart_priv # 4. 当前值是什么 $1 {state 2, rx {...}, ...} (gdb) info address uart_priv # 5. 物理地址对比 dump Symbol uart_priv is static at address 0x20001234.再配合info functions ^uart_把整套接口列出来整个驱动的轮廓 5 分钟内就能摸清。五、要点回顾你想知道…用什么这个类型长什么样字段偏移多少ptype/ptype/o这个全局变量定义在哪个文件info variables regex这个函数定义在哪签名是什么info functions regex这个地址是哪个符号info symbol addr这个符号的地址是多少info address sym三件套的共性只读符号表不依赖运行时。哪怕程序根本没跑起来只要 ELF 带调试信息就能用。这是它们在 coredump 分析里特别趁手的原因。ReferencesGDB 官方手册 · Symbol TablesGDB 官方手册 · Examining Data —ptype
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2617961.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!