为什么将GDB断点设置在x86程序集函数的错误地址



我遇到一个问题,gdb在添加断点时将行号映射到错误的内存地址。

下面的x86Linux汇编程序打印"hello"。

/* hello.s */
.section .data
str:
.ascii "hellon"
strlen = . - str
.section .text
print:
pushl %ebp
movl  %esp, %ebp
pushl %ebx
movl  $4, %eax
movl  $1, %ebx
movl  $str, %ecx
movl  $strlen, %edx
int   $0x80
popl  %ebx
movl  %ebp, %esp
popl  %ebp
ret
.globl _start
_start:
call  print
movl  $1, %eax
movl  $0, %ebx
int   $0x80

我用调试信息编译它,然后链接。

$ as -g --32 -o hello.o hello.s
$ ld -m elf_i386 -o hello hello.o

接下来,在gdb中,我尝试在第11行设置一个断点,即print函数(pushl %ebp)的第一行。

$ gdb ./hello
(gdb) break hello.s:11

0x8048078处的断点3:文件hello.s,第11行。

如输出所示,断点设置在地址0x8048078处。然而,那是错误的地址。当我在gdb中运行程序时,它在第14行中断。第11行的地址是0x8048074,使用gdb的info命令确认。

(gdb) info line hello.s:11

"hello.s"的第11行从地址0x8048074开始,到0x8048075结束。

直接在打印指令上设置断点有效(断点设置为第11行的地址0x8048074)。

为什么当我为第11行添加断点时,gdb不使用与使用上面的info命令输出的地址相同的地址?这是我试图破解的内存地址。

我在gdb 7.11.1和8.0.1上都遇到了相同的行为。我尝试添加.type print,@function注释,但这并没有解决我的问题。

是怎么来的

默认情况下,当您在函数或函数启动行上设置断点时,GDB会尝试跳过函数prolog。

这往往是C开发人员想要的,因为他们通常对参数设置不感兴趣。

如果您想要其他内容,请使用b *addressb &print来阻止GDB执行其常规操作。

最新更新