How to Include Debug Information with Nasm

How can I include debug information with nasm?

It looks like stabs format doesn't work with GDB, try DWARF instead ( http://en.wikipedia.org/wiki/DWARF )

compile with

nasm -f elf -g -F dwarf hello.asm

then in gdb type

start

then

si

you will see sources with comments so on. as Koray Tugay said there is most probably a bug in gdb.

Debug symbols in NASM (once more)

I am self-answering my own question based on a suggestion from @Michael Petch who was the person that actually found the root cause.

The issue was that I was using ld with -s which means "strip all", including debug symbols, i.e. I was undermining my own effort.

The correct commands should be:

nasm -g -F dwarf -f elf64 hello.asm
ld -o hello hello.o

Now, with gdb:

$ gdb ./hello 
GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
[.. snip copyright ..]
Reading symbols from ./hello...done.

(gdb) b _start
Breakpoint 1 at 0x400080: file hello.asm, line 7.

(gdb) run
Starting program: /home/terry/hello

Breakpoint 1, _start () at hello.asm:7
7 xor ebx, 0
(gdb)
$

Usage of %line directive in NASM with dwarf debug format does not result in expected line numbers

PUSH 1337 is on the line after the line you made line 1. So it seems %line sets the number of this line, and NASM's normal mechanism for counting line numbers continues to operate as normal. (Unlike GAS's deprecated .line which sets the line number of the next line.)

The RET is 2 lines after the last POP RAX, so that makes sense.

According to the manual, the full syntax includes an optional parameter to control line-number incrementing; apparently mmm defaults to 1:

%line nnn[+mmm] filename

So possibly (untested)

%line 1+0  test.txt

NASM -g is designed to make debug info for the asm source itself, not for the line numbers of some higher-level source file that was compiled to a .asm NASM file. The manual says it's intended for use with a macro-preprocessor (other than NASM's built-in macros), where it would make sense to have source line numbers increment.

But if you want to hack up that functionality, if +0 doesn't work, I guess you could keep resetting the %line before every instruction, with the same line number repeatedly for ones in a block that all came from the same higher-level source line.

And use the number before the one you want NASM to use. So I guess use %line 0 test.txt if you want the instruction on the next line to be reported as line 1 of test.txt, because 0 is the number before 1.

(Assuming NASM supports using 0 as a line number, and rewinding the line number to have the same line twice.)

I don't know of NASM directives equivalent in design to GAS's .loc which is intended for generating debug info for a C or other high-level source which compiled to a .s.

Line number debug information in my compiler

I guess you are looking for NASM's %line directive. (To generate debugging info, you need to use the -g command line flag.)

NASM Assembler Debugger

I used to compile assembly code with gas, and link it with ld, and then use gdb to debug it.
I don't know if it's applicable to you, but it should.

GDB does not load source lines from NASM

I setup an Ubuntu 22.04 VM and found that I could reproduce the issue that you are seeing there, however, on my local machine, I could not reproduce the problem.

I noticed that on my local machine I was using nasm 2.14.02, while on the Ubuntu machine I was using 2.15.05.

If we check the objdump -g output on the two executables, here's part of what I see from the working executable:

Contents of the .debug_info section (loaded from foo):

Compilation Unit @ offset 0x0:
Length: 0x45 (32-bit)
Version: 3
Abbrev Offset: 0x0
Pointer Size: 8
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
<c> DW_AT_low_pc : 0x401000
<14> DW_AT_high_pc : 0x40100c
<1c> DW_AT_stmt_list : 0x0
<20> DW_AT_name : foo.asm
<28> DW_AT_producer : NASM 2.14.02
<35> DW_AT_language : 32769 (MIPS assembler)
<1><37>: Abbrev Number: 2 (DW_TAG_subprogram)
<38> DW_AT_low_pc : 0x401000
<40> DW_AT_frame_base : 0x0 (location list)
<1><44>: Abbrev Number: 0

And here's the same part from the broken executable:

Contents of the .debug_info section (loaded from foo):

Compilation Unit @ offset 0x0:
Length: 0x45 (32-bit)
Version: 3
Abbrev Offset: 0x0
Pointer Size: 8
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
<c> DW_AT_low_pc : 0x401000
<14> DW_AT_high_pc : 0x401000
<1c> DW_AT_stmt_list : 0x0
<20> DW_AT_name : foo.asm
<28> DW_AT_producer : NASM 2.15.05
<35> DW_AT_language : 32769 (MIPS assembler)
<1><37>: Abbrev Number: 2 (DW_TAG_subprogram)
<38> DW_AT_low_pc : 0x401000
<40> DW_AT_frame_base : 0x0 (location list)
<1><44>: Abbrev Number: 0

The critical difference is the DW_AT_high_pc, this appears to be wrong with the 2.15.05 nasm. I manually went in and edited this value, and suddenly, I can debug the previously broken executable just fine.

This appears to be a regression in 2.15.05 of nasm, you should consider downgrading nasm (I think 2.15.05 is the current latest release), or maybe file a nasm bug.

Nasm : how to use ORG directive when you want debug symbol too?

This is to give a precise solution to your problem, in case others would be in the same situation:

If you want to set your binary origin to 0x7c00 (as in common kernel boot-loader)

ld -Ttext=0x7c00 --oformat binary -o Main.bin Main.elf


Related Topics



Leave a reply



Submit