最直接方式是用set logging on开启日志记录,所有命令输出自动追加到默认文件gdb.txt;可先set logging file指定路径再启用,需手动set logging off关闭,否则下次启动仍写入旧文件。

gdb里用set logging on捕获全部输出
最直接的方式是让gdb把整个调试会话(包括bt、info registers、print等所有命令结果)自动写入文件。关键不是“导出”,而是“开启日志记录”:
-
set logging on启用后,所有后续命令的输出都会追加到gdb.txt(默认名) - 想换文件名?先执行
set logging file /path/to/analysis.log,再set logging on - 日志只记录
gdb的输出,不包含你敲的命令本身;如果需要带命令历史,得额外用show commands或history手动补 - 注意:日志不会自动关闭,退出前最好执行
set logging off,否则下次启动gdb可能继续往旧文件写
只保存调用栈用bt > /tmp/stack.log
如果只需要崩溃点的函数调用链,bt支持重定向,比开全局日志更轻量:
-
bt > /tmp/stack.log—— 只存当前线程的栈,覆盖写 -
bt full > /tmp/stack_full.log—— 连局部变量一起保存,适合排查变量状态 -
thread apply all bt > /tmp/all_threads.log—— 多线程必须用这个,否则只看到主线程 - 路径必须可写,且
gdb进程有权限(比如在容器里挂载了/tmp,但没给chown,就可能失败)
分析完再导出不如一开始就用gdb -batch脚本化
人工交互式分析容易漏步骤,也难复现。生产环境建议用批处理模式一次性提取关键信息:
- 写一个命令文件
analyze.gdb:
set logging file /tmp/core_analysis.log set logging on bt full info registers info proc mappings quit
- 然后一条命令跑完:
gdb -batch -x analyze.gdb ./program ./core.1234 -
-batch模式下gdb不进交互,执行完就退出,适合集成进CI或运维脚本 - 注意:
-batch会静默忽略错误(比如符号文件缺失),所以得先确认./program带-g编译,且路径正确
别忘了core文件本身也要保留调试符号
保存下来的日志再全也没用,如果./program被strip过,bt只能显示地址,看不到函数名和行号:
- 检查有没有调试信息:
file ./program输出里要有with debug_info - 或者用
readelf -S ./program | grep debug看是否存在.debug_*节区 - 发布版本如果必须去符号,至少保留一份带
-g的副本,和core文件一起归档,否则日志里的#0 0x0001058c in strcpy ()这种信息基本等于没线索











