如何将 GDB tracepoint 信息保存为可读的 dump 文件?
要导出可直接阅读的文本文件,可以用 tfind 遍历 trace frame,用 tdump 输出数据,再通过 GDB 自带的日志功能保存。这样就能满足当前需求,无需编写 Python 脚本。
tsave 保存的是供后续分析使用的 trace 数据,没有直接输出 tdump 风格纯文本的选项。如果保存的文件无法回读,需要检查加载方式、GDB 版本和具体报错,不能仅凭“打不开”判断文件格式已经变化。
使用 GDB 日志导出文本
采集结束后,在能够正常执行 tfind 和 tdump 的 GDB 会话中运行:
set pagination off
set logging file output.txt
set logging overwrite on
set logging redirect off
set logging enabled on
tfind start
while ($trace_frame != -1)
tdump
tfind
end
set logging enabled off
这段命令从第一个 trace snapshot 开始,逐帧输出数据,直到没有选中的 snapshot。GDB 官方文档也用这种循环遍历 trace buffer。参考:tfind
各项日志设置的作用如下:
set logging overwrite on:本次开启日志时覆盖已有文件;需要追加时改为off。set logging redirect off:同时输出到终端和文件;只写文件时改为on。set pagination off:避免大量输出触发分页提示。
日志也会记录这段操作期间其他 GDB 命令的输出,例如 tfind 显示的帧信息。参考:Logging Output
如果旧版 GDB 不识别 set logging enabled on/off,可分别改用旧语法 set logging on 和 set logging off。参考:日志命令变更记录
使用 pipe 时要追加输出
如果只想保存 tdump 的输出,也可以继续使用原来的管道方案,将循环内的命令改为:
pipe tdump | tee -a output.txt
tee output.txt 每次执行都会覆盖文件,多帧情况下通常只留下最后一次输出。使用 tee -a 可以追加内容。如果每次导出都需要一份新报告,应在开始遍历前清空文件一次。
运行 GDB 的环境中需要有 tee。GDB 的 pipe 命令可以将指定 GDB 命令的输出交给 shell 命令处理。参考:Shell Commands
回读原生 tsave 文件
原生 trace 文件含有二进制数据,不能按普通文本报告阅读。保存时可以使用:
tsave trace.tfile
随后打开新的 GDB 会话,加载采集时对应的可执行文件和调试符号,再指定 trace 数据源:
file ./program
target tfile trace.tfile
tstatus
tfind start
tdump
将 ./program 替换为实际程序路径。回读后,也可以运行前面的日志导出循环。
加载 trace 文件应使用 target tfile,不要将它当成可执行文件或 core dump 加载。文件必须位于 GDB 所在主机能够访问的文件系统中。如果保存时用了 tsave -r,文件会位于远端,需要先让主机能够访问它。参考:Using Trace Files
CTF 无法打开时是否需要升级工具
先核对版本,再判断升级能否解决问题。GDB 18.1 的官方发布说明列出,该版本已移除 Common Trace Format 支持,删除了 target ctf,tsave 也不再接受 -ctf。因此,升级到这一版本无法恢复对旧 CTF trace 的读取能力。参考:GDB 18.1 发布说明
旧版 GDB 生成的 CTF 数据为何无法读取,或 Eclipse Compass 等外部分析器为何解析失败,仅凭题述信息还无法确定。需要记录生成端和读取端的版本、实际加载命令及完整报错,再判断是否存在兼容性问题。
如果只是需要可读报告,且当前会话中的 tdump 已经能正常工作,直接导出其输出即可,不必先解决外部查看器的问题。
导出时的数据限制
文本导出只能展示已经采集的数据。tdump 会根据 tracepoint 当前的 collection actions 打印表达式。如果采集完成后修改了 actions,要求读取当时未采集的变量,读取就可能失败。
对于含有 while-stepping 的 tracepoint,tdump 还需要用采集到的 $pc 区分命中帧和单步帧。缺少 $pc 时,部分帧可能无法按正确的 collection 列表显示,因此也不能直接将这类错误归因于文件损坏。参考:tdump
备注:内容仅供参考。
