崩溃后用GDB加载core文件执行bt即可显示调用栈,但需确保使用带调试符号的原程序可执行文件,否则仅显示地址;动态库也需含-g信息,否则对应层显示??;bt full可显示局部变量,但依赖完整调试符号;导出栈需set logging on,如gdb ./app -c core -ex "set logging on" -ex "bt full" -ex "quit"。

崩溃后直接用 gdb 加载 core 文件就能看到调用栈
不需要“保存”动作,bt(backtrace)命令一执行就立即显示当前线程的完整调用栈。你真正要做的,是确保能进得去、看得清——这取决于 core 文件和可执行文件是否匹配、是否有调试符号。
- 必须用**原程序的未 stripped 可执行文件**加载 core,否则
bt只显示地址(如0x7f...+0x123),不显示函数名和行号 - 如果程序用了动态库,且崩溃发生在库内,需确保该库也带
-g编译信息,否则bt在那一层会显示?? -
bt full比bt多输出局部变量值,但要求调试符号完整,否则可能报错或截断
gdb 里怎么把调用栈导出成文本文件
不能靠截图或手动复制,要用 set logging on 开启日志捕获,否则退出 gdb 后就没了。
- 启动 gdb 时加
-ex "set logging on":例如gdb ./myapp -c core.1234 -ex "set logging on" -ex "bt full" -ex "quit" - 默认日志写入
gdb.txt;想指定路径就先执行set logging file /tmp/stack.log - 注意:
set logging on只记录你后续输入的命令和输出,不包含 gdb 启动 banner 或警告信息 - 如果 core 很大、线程很多,
thread apply all bt输出量极大,建议先set logging file再开 log,避免刷屏漏内容
为什么 bt 显示不全或全是问号
不是 gdb 坏了,而是环境缺关键信息。最常见三种情况:
- 可执行文件被
strip过 → 重编译时加-g,别用strip ./myapp - core 文件生成时程序已卸载调试符号 → 检查
readelf -n core.1234 | grep -i debug,确认有没有NX note或GNU_DEBUGDATA - 崩溃在 libc 或 libstdc++ 内部,但系统没装
libc6-dbg或libstdc++6-12-dbg包 → Ubuntu/Debian 上运行sudo apt install libc6-dbg
多线程程序崩溃,只看主线程的 bt 会漏掉关键线索
主线程可能只是“替死鬼”,真凶在线程池或 signal handler 里。必须检查所有线程上下文。
-
info threads先看有多少线程、哪个处于running或stopped状态 -
thread apply all bt是最简方案;若只想看非空闲线程,可用thread apply all bt if $_thread != $_main_thread(gdb 10.2+) - 某个线程卡在
pthread_cond_wait或__lll_lock_wait?说明可能是死锁,不是段错误——这时候bt本身没意义,得结合info registers和x/20i $pc看指令现场


















