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

Tom*_*low 9 gdb reverse-debugging

(编辑:根据当前"技巧"下面的第一个答案似乎是使用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) {
Run Code Online (Sandbox Code Playgroud)

但是,指令和功能历史记录不可用:

(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'
Run Code Online (Sandbox Code Playgroud)

并且唯一可用的目标类型是完整的,另一个记录的类型"btrace"失败,"Target不支持分支跟踪".

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

Cir*_*四事件 6

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

更准确地说,您的内核必须支持英特尔处理器跟踪(英特尔PT).这可以在Linux中检查:

grep intel_pt /proc/cpuinfo
Run Code Online (Sandbox Code Playgroud)

另见:https://unix.stackexchange.com/questions/43539/what-do-the-flags-in-proc-cpuinfo-mean

这些命令仅适用于record btrace模式.

在GDB源代码提交中beab5d9,nat/linux-btrace.c:kernel_supports_pt检查我们是否可以输入btrace.进行以下检查:

  • 检查是否/sys/bus/event_source/devices/intel_pt/type存在并阅读type
  • 做一个syscall (SYS_perf_event_open, &attr, child, -1, -1, 0);读取type,看看它是否返回>=0.TODO:为什么不使用C包装器?

第一次检查对我失败:文件不存在.

内核方面

cd进入内核4.1源码并:

git grep '"intel_pt"'
Run Code Online (Sandbox Code Playgroud)

我们找到了arch/x86/kernel/cpu/perf_event_intel_pt.c哪个设置该文件.特别是,它确实:

if (!test_cpu_cap(&boot_cpu_data, X86_FEATURE_INTEL_PT))
    goto fail;
Run Code Online (Sandbox Code Playgroud)

intel_pt是先决条件.

我怎么找到的 kernel_supports_pt

第一个grep:

git grep 'Target does not support branch tracing.'
Run Code Online (Sandbox Code Playgroud)

这导致我们btrace.c:btrace_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
Run Code Online (Sandbox Code Playgroud)

虚拟框也不支持它:从VirtualBox VM中的gdb记录中提取执行日志

英特尔SDE

Intel SDE 7.21已具备此CPU功能,请检查:

./sde64 -- cpuid | grep 'Intel processor trace'
Run Code Online (Sandbox Code Playgroud)

但我不确定是否可以在其上运行Linux内核:https://superuser.com/questions/950992/how-to-run-the-linux-kernel-on-intel-software-development-emulator- SDE

其他GDB方法

更普遍的问题,软件解决方案效率较低: