如何在GDB中运行记录指令历史和函数调用历史记录? [英] How to run record instruction-history and function-call-history in GDB?
问题描述
(gdb)start
...临时断点5在0x8048460处:文件bang.cpp,第13行。
开始程序:/home/thomasg/temp/./bang
临时断点5,main()at bang.cpp:13
13 f(1000);
(gdb)记录
(gdb)继续
继续。
如果(d){
(gdb)信息记录
,bang.cpp中的断点3,f(d = 900):5
5有效记录目标:记录完整
记录模式:
记录的最小指令编号为1.
最高记录指令编号为1005.
日志包含1005条指令。
最大记录指令为200000.
(gdb)reverse-continue
继续。
断点3,f(d = 901)在bang.cpp:5
5如果(d){
(gdb)记录转到结尾
前进到(b)如果(d){
$,则在$ b $ c $ 5
#0 f(d = 900) b
$ b
然而指令和函数历史不可用:
$ $ $ $ $ $ $ $ $ $ $ $(gdb)记录指令-history
当你的目标是'record-full'时,你不能这么做
(gdb)记录function-call-history
当你的目标是'record -full'
并且唯一可用的目标类型已满,另一个记录类型btrace失败目标不支持分支追踪。
所以很可能它只是不支持这个目标,但因为它是现代主流(gdb 7.6.1- ubuntu,在amd64上运行Intel(R)Core(TM)i5-3570的Linux MintPetra)我希望我忽略了一个关键的步骤或配置?
看来除了支持它的CPU之外,没有其他解决方案。
更准确地说,您的内核必须支持英特尔处理器追踪(英特尔PT)。这可以在Linux中检查:
grep intel_pt / proc / cpuinfo
另请参阅: https://unix.stackexchange.com/questions/43539/what-do-the-flags-in-proc-cpuinfo-mean
这些命令仅适用于记录btrace
模式。
在GDB源提交 第一次检查失败:文件不存在。 b 内核端 cd进入内核4.1源代码和: 所以 我如何找到 首先grep为: 这导致我们将 虚拟箱不支持它:从VirtualBox虚拟机中的gdb记录中提取执行日志 beab5d9
,它是 nat / linux-btrace.c:kernel_supports_pt
,它检查我们是否可以输入 btrace
。执行以下检查:
/ sys / bus / event_source / devices / intel_pt / type
存在并读取类型
syscall(SYS_perf_event_open,& attr ,孩子,-1,-1,0);
读取类型
,看它是否返回> = 0
。 TODO:为什么不使用C封装?
$ b
git grep'intel_pt'
<我们发现设置该文件的 arch / x86 / kernel / cpu / perf_event_intel_pt.c
。特别是,它确实:
$ p $ if(!test_cpu_cap(& boot_cpu_data,X86_FEATURE_INTEL_PT))
goto fail;
intel_pt
是先决条件。
kernel_supports_pt
git grep'目标不支持分支追踪'
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
$ b Intel SDE
Intel SDE 7.21 a>已经有了这个CPU功能,用下面的方法检查:
./ sde64 - cpuid | grep'Intel processor trace'
但我不确定Linux内核是否可以运行: https://superuser.com / questions / 950992 / how-to-run-the-linux-kernel-on-intel-software-development-emulator-sde
其他GDB方法
更常见的问题,使用效率较低的软件解决方案:
(EDIT: per the first answer below the current "trick" seems to be using an Atom processor. But I hope some gdb guru can answer if this is a fundamental limitation, or whether there adding support for other processors is on the roadmap?)
Reverse execution seems to be working in my environment: I can reverse-continue, see a plausible record log, and move around within it:
(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) {
However the instruction and function histories aren't available:
(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'
And the only target type available is full, the other documented type "btrace" fails with "Target does not support branch tracing."
So quite possibly it just isn't supported for this target, but as it's a mainstream modern one (gdb 7.6.1-ubuntu, on amd64 Linux Mint "Petra" running an "Intel(R) Core(TM) i5-3570") I'm hoping that I've overlooked a crucial step or config?
It seems that there is no other solution except a CPU that supports it.
More precisely, your kernel has to support Intel Processor Tracing (Intel PT). This can be checked in Linux with:
grep intel_pt /proc/cpuinfo
See also: https://unix.stackexchange.com/questions/43539/what-do-the-flags-in-proc-cpuinfo-mean
The commands only works in record btrace
mode.
In the GDB source commit beab5d9
, it is nat/linux-btrace.c:kernel_supports_pt
that checks if we can enter btrace
. The following checks are carried out:
- check if
/sys/bus/event_source/devices/intel_pt/type
exists and read thetype
- do a
syscall (SYS_perf_event_open, &attr, child, -1, -1, 0);
with the readtype
, and see if it returns>=0
. TODO: why not use the C wrapper?
The first check fails for me: the file does not exist.
Kernel side
cd into the kernel 4.1 source and:
git grep '"intel_pt"'
we find arch/x86/kernel/cpu/perf_event_intel_pt.c
which sets up that file. In particular, it does:
if (!test_cpu_cap(&boot_cpu_data, X86_FEATURE_INTEL_PT))
goto fail;
so intel_pt
is a pre-requisite.
How I've found kernel_supports_pt
First grep for:
git grep 'Target does not support branch tracing.'
which leads us to btrace.c:btrace_enable
. After a quick debug with:
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
Virtual box does not support it either: Extract execution log from gdb record in a VirtualBox VM
Intel SDE
Intel SDE 7.21 already has this CPU feature, checked with:
./sde64 -- cpuid | grep 'Intel processor trace'
But I'm not sure if the Linux kernel can be run on it: https://superuser.com/questions/950992/how-to-run-the-linux-kernel-on-intel-software-development-emulator-sde
Other GDB methods
More generic questions, with less efficient software solutions:
- call graph: List of all function calls made in an application
- instruction trace: Displaying each assembly instruction executed in gdb
这篇关于如何在GDB中运行记录指令历史和函数调用历史记录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!