dannyadam
dannyadam

Reputation: 4170

Why is GDB breakpoint set at the wrong address for an x86 assembly function?

I am experiencing an issue where gdb is mapping a line number to the wrong memory address when adding a breakpoint.

The following x86 Linux assembly program prints "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

I compile it with debugging information, and then link.

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

Next, in gdb, I try to set a breakpoint on line 11, the first line of the print function (pushl %ebp).

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

Breakpoint 3 at 0x8048078: file hello.s, line 11.

As shown in the output, the breakpoint is set at address 0x8048078. However, that is the wrong address. When I run my program in gdb, it breaks at line 14. The address of line 11 is 0x8048074, confirmed using gdb's info command.

(gdb) info line hello.s:11

Line 11 of "hello.s" starts at address 0x8048074 and ends at 0x8048075 .

Setting a breakpoint on the print instruction directly works (the break point is set for the address of line 11, 0x8048074).

How come when I add a breakpoint for line 11, gdb does not use the same address as output by using the info command above? This is the memory address I am trying to break on.

I am experiencing the same behavior on both gdb 7.11.1 and 8.0.1. I have tried adding a .type print,@function annotation, but that did not solve my issue.

Upvotes: 2

Views: 2363

Answers (1)

Employed Russian
Employed Russian

Reputation: 213375

How come

By default, GDB tries to skip past function prolog, when you set a breakpoint on a function, or a line on which the function starts.

This tends to be what C developers want, since they usually aren't interested in parameter setup.

If you want something else, use b *address or b &print to prevent GDB from doing its usual thing.

Upvotes: 5

Related Questions