bt full 比 bt 多显示每个栈帧的局部变量值和函数参数值,能精准定位空指针、参数异常或状态不一致问题,但依赖调试符号且可能因优化或栈损坏导致信息缺失或卡顿。

bt 和 bt full 的输出内容差异
最直接的区别是:bt 只显示调用栈帧的函数名、地址和源码位置;bt full 在此基础上,额外打印每个帧的局部变量值和函数参数值。
比如某次崩溃时:bt 会告诉你 process_request 调用了 update_cache,但不会告诉你 update_cache 当时收到的 key 是什么、entry->version 是多少;而 bt full 会一并显示:
#3 0x000055555555a8e2 in update_cache (key=0x7fffffffdb70 "user:1001") at cache.c:112 entry = 0x5555557789a0 version = 42
这对定位空指针、越界访问、状态不一致等问题非常关键。
什么时候必须用 bt full
当你怀疑问题出在「传入参数异常」或「局部变量状态错误」时,bt full 是不可替代的。
- 段错误(
Segmentation fault)发生在函数内部,但你不确定是哪个指针为NULL或已释放 —— 看bt full里参数和局部变量的值 - 逻辑分支走错,比如
if (entry->version != db_version)判定失败 —— 需要确认两个变量当时的实际值 - 调试多线程问题时,某个线程卡在锁等待,但不知道它上次操作了哪个缓存项 ——
bt full可能暴露刚写入的cache_key
注意:bt full 依赖调试符号完整。如果编译时没加 -g,或优化级别太高(如 -O3),部分变量可能被优化掉,显示为 <optimized out></optimized>。
bt full 的性能与副作用
bt full 不会改变程序状态,但比 bt 耗时略高,尤其在深度递归或大量局部变量的帧中。
- 对栈深度超过 100 层的场景,
bt full可能明显卡顿;此时可用bt full 10限制只看最近 10 帧 - 某些变量是大型结构体或数组,
bt full会尝试展开全部字段,导致输出冗长;可配合frame+p手动查关键字段 - 若某帧的变量值本身已损坏(如栈溢出覆盖),
bt full可能报错或显示乱码,这时退回到bt更稳妥
容易被忽略的细节
很多人以为 bt full 就是“更全的 bt”,但其实它默认只显示当前线程的栈。如果你在多线程程序中遇到问题:
- 先运行
info threads确认所有线程状态 - 用
thread apply all bt full查所有线程的完整帧信息 —— 否则可能漏掉真正出问题的线程 -
bt full不显示寄存器值,要看$rdi、$rsi等参数寄存器,得单独执行info registers
另外,bt full 显示的变量值是“该帧被压入栈时的快照”,不是实时值;如果变量在函数内被多次修改,看到的是初始传入或首次赋值后的状态。


















