如何在GDB中运行记录指令历史和函数调用历史记录? [英] How to run record instruction-history and function-call-history in GDB?

查看:1966
本文介绍了如何在GDB中运行记录指令历史和函数调用历史记录?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(编辑:根据当前技巧下面的第一个答案似乎是使用Atom处理器,但我希望有些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源提交 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
$ b

内核端

cd进入内核4.1源代码和:

  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



首先grep为:

  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 

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


$ 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 the type
  • do a syscall (SYS_perf_event_open, &attr, child, -1, -1, 0); with the read type, 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:

这篇关于如何在GDB中运行记录指令历史和函数调用历史记录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆