Debugging NASM local labels with gdb

Viewed 172

I have been having some issues debugging code assembled by nasm with gdb: it seems like gdb doesn't do well with nasm local labels. nasm generates a local symbol named «function».label, which seems to confuse gdb, as it loses track of which function it is in.

Here is one scenario in which it gives a sub-optimal debugging experience:

section .text

global _start

_start:
  call foo
  ud2

foo:
  push rbp
  mov rbp, rsp
  call bar
.end:
  pop rbp
  ret

bar:
  ret

Compile and debug:

$ nasm -f elf64 -g -F DWARF example.asm -o example.o
$ ld example.o -o example
$ gdb ./example
Reading symbols from ./example...done.
(gdb) b foo
Breakpoint 1 at 0x400087: file example.asm, line 10.
(gdb) run
Starting program: /home/mvanotti/orga2/gdb/example 

Breakpoint 1, foo () at example.asm:10
10        push rbp
(gdb) ni
11        mov rbp, rsp
(gdb) ni
12        call bar
(gdb) ni

Program received signal SIGILL, Illegal instruction.
_start () at example.asm:7
7         ud2

As you can see, nexti continues execution even after the return from the bar function call. I believe this is caused because the next instruction in foo belongs to the foo.end symbol, causing gdb to not recognize that as the return point of the function. Adding any other instruction before the .end label in the asm file fixes the issue.

Similarly, the backtrace gets all messed up when it steps into a local label:

(gdb) 
foo.end () at example.asm:14
14        pop rbp
(gdb) bt
#0  foo.end () at example.asm:14
#1  0x0000000000000000 in ?? ()
(gdb) 

This also affects yasm and lldb.

There is not a clear workaround for this. I couldn't find an option in nasm to not emit the function.label symbols, or an easy way to remove them. strip for example, lets you specify the --wildcard option, but the regexp syntax is too basic and cannot match something like .+\.*. The closest I got was strip --wildcard -N "*.*", but that also matches .something

In gas, this is solved by creating a label in the form of .Llocal_label$ which gets discarded automatically by ld.

0 Answers
Related