PAYATHON 2026

如何将 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

备注:内容仅供参考。