ChatGPT解决这个技术问题 Extra ChatGPT

在 GDB 中显示当前的汇编指令

我正在 GDB 中进行一些汇编级调试。有没有办法让 GDB 以与显示当前源代码行相同的方式向我显示当前的汇编指令?每个命令后的默认输出如下所示:

0x0001433f      990         Foo::bar(p);

这给了我当前指令的地址,但我必须继续参考 disassemble 的输出才能查看我当前正在执行的指令。


P
Peter Mortensen

您可以在 GDB 中切换到程序集布局:

(gdb) layout asm

有关详细信息,请参阅 here。当前的汇编指令将显示在汇编窗口中。

   ┌───────────────────────────────────────────────────────────────────────────┐
   │0x7ffff740d756 <__libc_start_main+214>  mov    0x39670b(%rip),%rax        #│
   │0x7ffff740d75d <__libc_start_main+221>  mov    0x8(%rsp),%rsi              │
   │0x7ffff740d762 <__libc_start_main+226>  mov    0x14(%rsp),%edi             │
   │0x7ffff740d766 <__libc_start_main+230>  mov    (%rax),%rdx                 │
   │0x7ffff740d769 <__libc_start_main+233>  callq  *0x18(%rsp)                 │
  >│0x7ffff740d76d <__libc_start_main+237>  mov    %eax,%edi                   │
   │0x7ffff740d76f <__libc_start_main+239>  callq  0x7ffff7427970 <exit>       │
   │0x7ffff740d774 <__libc_start_main+244>  xor    %edx,%edx                   │
   │0x7ffff740d776 <__libc_start_main+246>  jmpq   0x7ffff740d6b9 <__libc_start│
   │0x7ffff740d77b <__libc_start_main+251>  mov    0x39ca2e(%rip),%rax        #│
   │0x7ffff740d782 <__libc_start_main+258>  ror    $0x11,%rax                  │
   │0x7ffff740d786 <__libc_start_main+262>  xor    %fs:0x30,%rax               │
   │0x7ffff740d78f <__libc_start_main+271>  callq  *%rax                       │
   └───────────────────────────────────────────────────────────────────────────┘
multi-thre process 3718 In: __libc_start_main     Line: ??   PC: 0x7ffff740d76d
#3  0x00007ffff7466eb5 in _IO_do_write () from /lib/x86_64-linux-gnu/libc.so.6
#4  0x00007ffff74671ff in _IO_file_overflow ()
   from /lib/x86_64-linux-gnu/libc.so.6
#5  0x0000000000408756 in ?? ()
#6  0x0000000000403980 in ?? ()
#7  0x00007ffff740d76d in __libc_start_main ()
   from /lib/x86_64-linux-gnu/libc.so.6
(gdb)

@greatwolf,看起来您的 gdb 中没有 tui 支持。有关详细信息,请参阅此问题:stackoverflow.com/q/6706838/72178
整洁的!现在我可以有一个类似的寄存器窗口吗?我确实可以:layout regs
另请参阅 gdb docs for other TUI commands,如 tui reg vector 以显示向量 regs 而不是整数 regs。 (但并不总是非常有用,因为它不允许您只选择 .v8_int16 或其他东西,因此显示非常混乱。)请参阅 x86 tag wiki 以获取调试 asm 的快速教程。
那是关于一个无用的功能和输出。 C++ 损坏的名称太长,我试图查看的所有内容都在右侧的屏幕之外。多么愚蠢的决定(在 si 时默认不显示 ASM),多么无用的功能(不显示必要信息的视口)。否决这个答案是没有意义的,因为你只是信使......
同样,·layout src 调试时查看源代码,也值得记住通过 CTRL+x+a 退出此模式
E
Employed Russian

你可以做

display/i $pc

并且每次GDB停止时,都会显示下一条指令的反汇编。

GDB-7.0 还支持 set disassemble-next-line on,它将反汇编整个下一行,并为您提供更多反汇编上下文。


使用 si(而不是 s)时,我们如何启用此功能?
您还可以在此处使用 display/ni $pc 来显示 n 说明,例如在对 stackoverflow.com/a/1902906/129550 的评论中
b
bmargulies

命令

x/i $pc

可以使用通常的配置机制设置为一直运行。


x/ni $pc 查看接下来的 n 条指令,这通常非常有用。
一直运行命令的配置机制是什么?
J
Jakuje

设置以下选项:

set  disassemble-next-line on
show disassemble-next-line

将为您提供如下所示的结果:

(gdb) stepi
0x000002ce in ResetISR () at startup_gcc.c:245
245 {
   0x000002cc <ResetISR+0>: 80 b5   push    {r7, lr}
=> 0x000002ce <ResetISR+2>: 82 b0   sub sp, #8
   0x000002d0 <ResetISR+4>: 00 af   add r7, sp, #0
(gdb) stepi
0x000002d0  245 {
   0x000002cc <ResetISR+0>: 80 b5   push    {r7, lr}
   0x000002ce <ResetISR+2>: 82 b0   sub sp, #8
=> 0x000002d0 <ResetISR+4>: 00 af   add r7, sp, #0

我的安装中似乎不存在此选项。它被删除了吗?
@fuz更有可能,您的gdb很旧
@fuz 至少存在于 Ubuntu 18.04 的 GDB 8.1 中。
很有用的技能
show disassemble-next-line 用于测试,打印标志状态,开或关
m
mohit

如果您希望在单步执行程序时自动显示接下来的几条指令,您可以使用 display 命令,如下所示 -

display /3i $pc

每当遇到断点或单步执行程序时,上面将显示 3 条指令。

博客条目 here 中的更多详细信息。


C
Ciro Santilli Путлер Капут 六四事

GDB 仪表板

https://github.com/cyrus-and/gdb-dashboard

此 GDB 配置使用官方 GDB Python API 向我们展示我们想要的任何内容,只要 GDB 在例如 next 之后停止,就像 TUI。

但是,我发现此实现是内置 GDB TUI 模式的更强大且可配置的替代方案,如下所述:gdb split view with code

例如,我们可以配置 GDB Dashboard 以显示反汇编、源代码、寄存器和堆栈:

dashboard -layout source assembly registers stack

如果您改为启用所有可用视图,则如下所示:

https://i.stack.imgur.com/mHC8f.png

相关问题:

在 gdb 中切换到汇编


@downvoters:请解释一下,以便我可以学习和改进信息。我相信这是 TUI 目前接受的答案的更好选择:stackoverflow.com/a/2015523/895245
Santilli 这是一个非常有用的工具。但是我在使用的时候,只能看当前代码位置附近的代码。有时代码执行到第n行,但我想看看其他位置的代码是什么(比如某个函数)?有什么办法可以让显示代码的位置滑动(如果汇编代码可以滑动就更好了)?
@cyj 嗨,你想在每一步之后显示特定函数的反汇编吗?或者只是在不时手动输入给定命令之后?
它不需要一直显示。只是有时我想看看其他位置的代码是什么。所以调试的时候可以大致知道结果是什么。不知道能不能滚动显示代码的位置,因为调试的时候,只显示正在执行的代码附近的几行代码,这让我无法根据上下文理解。
@cyj 如果是当前文件,我经常使用 edit 命令打开 vim 中的代码: vi.stackexchange.com/questions/2046/… 如果是在另一个文件中,我倾向于只使用 Eclipse 并跳转到附近函数的定义Ctrl + Shift + T :-) 不完美,但足够好。
a
abhi

在 gdb 中按 Ctrl x 2,屏幕将分成 3 个部分。

第一部分将向您展示高级语言的普通代码。

第二个将向您显示程序集等效项和相应的 instruction Pointer

第三个将向您显示正常的 gdb 提示以输入命令。

https://i.stack.imgur.com/tiVcg.png


我无法使用 Ctrl-X 2 启动它,但它看起来像 gdb -tui 模式,这很棒。
这也可以通过 gdb 提示符中的 layout split 访问。
T
Tom

有一个简单的解决方案是使用 stepi,它依次向前移动 1 个 asm 指令并显示周围的 asm 代码。