gdb 下断点但不显示 int3 指令

问题描述 投票:0回答:1

我正在学习 gdb 中的 int 3 指令和断点。 但我发现了一些奇怪的事情。 我的c代码如下:

#include<stdio.h>
int main(int argc, char *argv[]) {
        int a = 4;
        a += 3;
        int b = 4;
        int c = b*a;
        printf("%d\n", c);
        return 0;
}

然后编译:

gcc ./test.c

然后使用gdb,输出如下:

[xxx@xxxx 23:29:23 ~]
$ gdb ./a.out
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./a.out...
(No debugging symbols found in ./a.out)
(gdb) run
Starting program: /home/heyuanhong/a.out
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
28
[Inferior 1 (process 179733) exited normally]
(gdb) disassemble main
Dump of assembler code for function main:
   0x0000555555555149 <+0>:     endbr64
   0x000055555555514d <+4>:     push   %rbp
   0x000055555555514e <+5>:     mov    %rsp,%rbp
   0x0000555555555151 <+8>:     sub    $0x20,%rsp
   0x0000555555555155 <+12>:    mov    %edi,-0x14(%rbp)
   0x0000555555555158 <+15>:    mov    %rsi,-0x20(%rbp)
   0x000055555555515c <+19>:    movl   $0x4,-0xc(%rbp)
   0x0000555555555163 <+26>:    addl   $0x3,-0xc(%rbp)
   0x0000555555555167 <+30>:    movl   $0x4,-0x8(%rbp)
   0x000055555555516e <+37>:    mov    -0x8(%rbp),%eax
   0x0000555555555171 <+40>:    imul   -0xc(%rbp),%eax
   0x0000555555555175 <+44>:    mov    %eax,-0x4(%rbp)
   0x0000555555555178 <+47>:    mov    -0x4(%rbp),%eax
   0x000055555555517b <+50>:    mov    %eax,%esi
   0x000055555555517d <+52>:    lea    0xe80(%rip),%rax        # 0x555555556004
   0x0000555555555184 <+59>:    mov    %rax,%rdi
   0x0000555555555187 <+62>:    mov    $0x0,%eax
   0x000055555555518c <+67>:    call   0x555555555050 <printf@plt>
   0x0000555555555191 <+72>:    mov    $0x0,%eax
   0x0000555555555196 <+77>:    leave
   0x0000555555555197 <+78>:    ret
End of assembler dump.
(gdb) b *0x0000555555555171
Breakpoint 1 at 0x555555555171
(gdb) x/1bx 0x0000555555555171
0x555555555171 <main+40>:       0x0f
(gdb) disassemble main
Dump of assembler code for function main:
   0x0000555555555149 <+0>:     endbr64
   0x000055555555514d <+4>:     push   %rbp
   0x000055555555514e <+5>:     mov    %rsp,%rbp
   0x0000555555555151 <+8>:     sub    $0x20,%rsp
   0x0000555555555155 <+12>:    mov    %edi,-0x14(%rbp)
   0x0000555555555158 <+15>:    mov    %rsi,-0x20(%rbp)
   0x000055555555515c <+19>:    movl   $0x4,-0xc(%rbp)
   0x0000555555555163 <+26>:    addl   $0x3,-0xc(%rbp)
   0x0000555555555167 <+30>:    movl   $0x4,-0x8(%rbp)
   0x000055555555516e <+37>:    mov    -0x8(%rbp),%eax
   0x0000555555555171 <+40>:    imul   -0xc(%rbp),%eax
   0x0000555555555175 <+44>:    mov    %eax,-0x4(%rbp)
   0x0000555555555178 <+47>:    mov    -0x4(%rbp),%eax
   0x000055555555517b <+50>:    mov    %eax,%esi
   0x000055555555517d <+52>:    lea    0xe80(%rip),%rax        # 0x555555556004
   0x0000555555555184 <+59>:    mov    %rax,%rdi
   0x0000555555555187 <+62>:    mov    $0x0,%eax
   0x000055555555518c <+67>:    call   0x555555555050 <printf@plt>
   0x0000555555555191 <+72>:    mov    $0x0,%eax
   0x0000555555555196 <+77>:    leave
   0x0000555555555197 <+78>:    ret
End of assembler dump.

首先,我在主函数中打印汇编代码,然后在地址中设置断点

0x0000555555555171
。之后我尝试打印
0x0000555555555171
的值,然后再次打印汇编代码。

我的问题是为什么在地址

0x0000555555555171
(imul -0xc(%rbp),%eax)中创建断点后,
int 3
(操作码是
0xcc
)指令不显示?

我认为地址

0x0000555555555171
应该是
0xcc
,因为我只是set断点,并没有hit断点。

我的操作系统是ubuntu 22.04,gcc版本是11.4.0,CPU是Intel(R) Core(TM) i9-14900KF

linux debugging gdb
1个回答
0
投票

总结其他人在评论中的回答:

  1. 并非每种类型的断点都需要使用
    0xCC
    指令的
    int3
    操作码覆盖程序文本
  2. GDB仅在即将将控制权转移给下级(正在调试)程序时插入断点,并在GDB获得控制权后(即程序在断点处停止时)删除断点。这是由
    set breakpoint always-inserted on
    (默认为
    off
    )控制的。
  3. 即使断点被插入,GDB
    disas
    假装它们不存在,因为通常你想看到原始的反汇编,而不是你会得到的被破坏的图片,其中原始反汇编被随机覆盖
     0xCC
    操作码(使被覆盖的指令的其余部分变得毫无意义或只是错误的)。
  4. 如果您确实想观察 GDB 修改的代码,您可以让下级(在运行时)将代码字节复制到单独的缓冲区。当断点被击中时,您可以使用
    disas
    检查该缓冲区中的指令,您将看到 actual 指令,其中散布着
    int3
    操作码。
© www.soinside.com 2019 - 2024. All rights reserved.