本文介绍了显示在 gdb 中执行的每条汇编指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前有一个棘手的错误发生在我无法访问源代码或符号的地方,即我可以看到发生崩溃的指令及其地址,但仅此而已.我想做的是让 gdb 在不需要交互的情况下运行并显示每条指令,但我还没有找到方法.

I currently have a tricky bug that occurs in a place where I don't have access to source or symbols, i.e. I can see the instruction and its address where the crash occurs, but that's about it. What I'd like to do is have gdb run without requiring interaction and display every instruction as it does so, but I've yet to find a way to do it.

我希望实现的是这样的:

What I'm hoping to achieve is something like this:

(gdb) /* some command */
0x2818a7c0: push   %ebp
0x2818a7c1: mov    %esp,%ebp
0x2818a7c3: push   %ebx
0x2818a7c4: sub    $0x4,%esp
...
0x28563622: mov    %esi,0x0(%eax)
Program received signal SIGSEGV, Segmentation fault.

我一直在为程序计数器设置一个显示,如下所示:

What I've been doing is setting up a display for the program counter, like so:

(gdb) display/i $pc

然后用 stepi 运行代码:

(gdb) stepi
1: x/i $pc  0x2818a7c0: push   %ebp

但是,崩溃是在数百或数千条指令之外,我想要一种方法来查看每条指令(如果更可取,一起查看),而不必多次点击输入".此外,如果我要手动执行此操作,我会在每条指令之间看到 (gdb) 提示,这不太理想.

However, the crash is hundreds or thousands of instructions away, and I'd like a way to see each one (together, if preferable), without having to hit "enter" that many times. Also, if I were to do it manually, I'd see a (gdb) prompt between each instruction, which is less than desirable.

我简要研究过的一条路线是 脚本,但我唯一的想法是在 main() 设置,让它显示和另一个中断(用于下一条指令),然后继续,但我可以'不要在 commands 块中使用 commands,所以它不会像我想象的那样工作.

One route I've briefly looked into is scripting, but my only thought is to setup at main(), have it display and another break (for the next instruction), and then continue, but then I can't use commands within a commands block, so it wouldn't work the way I'm imagining it.

以防万一,我正在开发 FreeBSD.

In case it matters, I'm working on FreeBSD.

推荐答案

以下应该满足您的要求:

The following should do what you asked for:

# not strictly required, but you'll likely want the log anyway
(gdb) set logging on

# ask gdb to not stop every screen-full
(gdb) set height 0

(gdb) while 1
 > x/i $pc
 > stepi
 > end

然而,这种调试方法可能会被证明是徒劳的:即使在大多数琐碎的程序中,执行的指令也只是太多.

However, this approach to debugging will likely prove futile: there are simply too many instructions executed even in most trivial programs.

更好的方法可能是运行程序直到崩溃,尝试了解当前函数正在做什么以及谁调用它,并适当地设置断点.

A better approach might be to run the program until crash, attempt to understand what current function is doing and who calls it, and setting breakpoints appropriately.

在 x86 上,即使在完全剥离的可执行文件中,您通常也可以推断出函数边界.

On x86, you can often deduce function boundaries even in fully stripped executable.

您需要查看的另一件事是 strace/truss 输出,因此您可以看到紧接在崩溃点之前的系统调用.

Another thing you'll want to look at is strace/truss output, so you can see what system calls immediately precede the crash point.

这篇关于显示在 gdb 中执行的每条汇编指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 05:49