我遇到一个问题,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中,我尝试在第11行设置断点,第11行是打印函数的第一行(pushl %ebp
)。
$ gdb ./hello
(gdb) break hello.s:11
断点3位于0x8048078:文件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
注释,但这并没有解决我的问题。
答案 0 :(得分:4)
怎么来
默认情况下,当您在函数上设置断点或函数启动的行时,GDB会尝试跳过函数序言。
这往往是C
开发人员想要的,因为他们通常对参数设置不感兴趣。
如果您还想要其他内容,请使用b *address
或b &print
来阻止GDB执行其常规操作。