如何在GDB中运行记录指令历史和函数调用历史?
(编辑:根据下面的第一个答案,当前的“技巧”似乎是使用Atom处理器。但我希望一些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
(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)使用读取的
键入
,查看它是否返回
。TODO:为什么不使用C包装器呢=0
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方法
更一般的问题,效率更低的软件解决方案:
- 调用图:
- 指令跟踪:
./sde64 -- cpuid | grep 'Intel processor trace'