如何在GDB中运行记录指令历史和函数调用历史?

如何在GDB中运行记录指令历史和函数调用历史?,gdb,trace,reverse-debugging,Gdb,Trace,Reverse Debugging,(编辑:根据下面的第一个答案,当前的“技巧”似乎是使用Atom处理器。但我希望一些gdb专家能够回答这是否是一个基本限制,或者是否有增加对其他处理器的支持的路线图?) 反向执行似乎在我的环境中起作用:我可以继续反向执行,查看看似合理的记录日志,并在其中移动: (gdb) start ...Temporary breakpoint 5 at 0x8048460: file bang.cpp, line 13. Starting program: /home/thomasg/temp/./bang

(编辑:根据下面的第一个答案,当前的“技巧”似乎是使用Atom处理器。但我希望一些gdb专家能够回答这是否是一个基本限制,或者是否有增加对其他处理器的支持的路线图?)

反向执行似乎在我的环境中起作用:我可以继续反向执行,查看看似合理的记录日志,并在其中移动:

(gdb) start
...Temporary breakpoint 5 at 0x8048460: file bang.cpp, line 13.
Starting program: /home/thomasg/temp/./bang 

Temporary breakpoint 5, main () at bang.cpp:13
13    f(1000);
(gdb) record 
(gdb) continue 
Continuing.

Breakpoint 3, f (d=900) at bang.cpp:5
5     if(d) {
(gdb) info record 
Active record target: record-full
Record mode:
Lowest recorded instruction number is 1.
Highest recorded instruction number is 1005.
Log contains 1005 instructions.
Max logged instructions is 200000.
(gdb) reverse-continue 
Continuing.

Breakpoint 3, f (d=901) at bang.cpp:5
5     if(d) {
(gdb) record goto end
Go forward to insn number 1005
#0  f (d=900) at bang.cpp:5
5     if(d) {
但是,指令和功能历史记录不可用:

(gdb) record instruction-history 
You can't do that when your target is `record-full'
(gdb) record function-call-history 
You can't do that when your target is `record-full'
并且唯一可用的目标类型是full,另一个有文档记录的类型“btrace”失败,并显示“target不支持分支跟踪”

所以很可能这个目标不支持它,但由于它是主流的现代版本(gdb 7.6.1-ubuntu,在amd64 Linux Mint“Petra”上运行“Intel(R)Core(TM)i5-3570”),我希望我忽略了一个关键步骤或配置?

至少是部分答案(对于“我做错了吗”方面)

*添加了一个新的记录目标“record btrace”。新目标 使用硬件支持来记录进程的控制流。信息技术 不支持重播执行,但它实现 下面是用于调查记录的执行日志的新命令。 可通过以下方式启用此新记录方法: 记录赛跑 “record btrace”目标仅在Intel Atom处理器上可用 并且需要Linux内核2.6.32或更高版本。 *为记录/重播添加了两个新命令以提供信息 关于记录的执行,而不必重播执行。 仅“record btrace”支持这些命令。 记录指令历史记录在以下位置打印执行历史记录: 指令粒度 记录函数调用历史记录在以下位置打印执行历史记录: 功能粒度 我并不经常羡慕Atom处理器的所有者;-)


我将编辑该问题,以重新关注解决方案或未来支持计划的问题。

似乎除了支持它的CPU之外,没有其他解决方案

更准确地说,内核必须支持英特尔处理器跟踪(Intel PT)。这可以在Linux中通过以下方式进行检查:

grep intel_pt /proc/cpuinfo
另见:

这些命令仅在
record btrace
模式下工作

在GDB源代码提交
beab5d9
中,检查是否可以进入
btrace
的是
nat/linux btrace.c:kernel\u supports\u pt
。执行以下检查:

  • 检查
    /sys/bus/event\u source/devices/intel\u pt/type
    是否存在,并读取
    type
  • 执行
    syscall(SYS\u perf\u event\u open,&attr,child,-1,-1,0)键入
    ,查看它是否返回
    =0
    。TODO:为什么不使用C包装器呢
第一次检查失败:文件不存在

内核端

将cd放入内核4.1源代码中,并:

git grep '"intel_pt"'
我们找到了设置该文件的
arch/x86/kernel/cpu/perf\u event\u intel\u pt.c
。特别是,它确实:

if (!test_cpu_cap(&boot_cpu_data, X86_FEATURE_INTEL_PT))
    goto fail;
因此,
intel\u pt
是一个先决条件

我如何找到
内核支持\u pt

第一个grep用于:

git grep 'Target does not support branch tracing.'
这将导致我们进入
btrace.c:btrace\u enable
。使用以下工具快速调试后:

gdb -q -ex start -ex 'b btrace_enable' -ex c --args /home/ciro/git/binutils-gdb/install/bin/gdb --batch -ex start -ex 'record btrace' ./hello_world.out
虚拟盒也不支持它:

英特尔SDE

已具有此CPU功能,请检查:

./sde64 -- cpuid | grep 'Intel processor trace'
但我不确定Linux内核是否可以在其上运行:

其他GDB方法

更一般的问题,效率更低的软件解决方案:

  • 调用图:
  • 指令跟踪:

精彩的答案,有很多丰富的链接-我没有把PT当作同义词/底层技术()-谢谢!
./sde64 -- cpuid | grep 'Intel processor trace'