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

以下x86 Linux汇编程序显示“hello”。

/* hello.s */

  .section .data
str:
  .ascii "hello\n"
  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中,我尝试在打印功能(pushl %ebp)的第一行第11行设置一个断点。
$ gdb ./hello
(gdb) break hello.s:11



如输出所示,断点设置在地址0x8048078上。但是,这是错误的地址。当我在gdb中运行程序时,它在第14行中断。第11行的地址是0x8048074,已使用gdb的info命令进行了确认。
(gdb) info line hello.s:11



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

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

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

最佳答案



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

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

如果需要其他功能,请使用b *addressb &print阻止GDB正常执行操作。

10-07 19:47
查看更多