Reputation: 115
I am writing assembly language program using nasm on linux. The problem is during debugging using gdb it does not step inside the _start function and gives the message "Single stepping until exit from function _start,"
Also, when I set break points after line 1 it says:
(gdb) break 2
Note: breakpoints 1 and 2 also set at pc 0x4000b0.
Breakpoint 3 at 0x4000b0: file new3.asm, line 2.
(gdb) break 3
Note: breakpoints 1, 2 and 3 also set at pc 0x4000b0.
Breakpoint 4 at 0x4000b0: file new3.asm, line 3.
I am assembling and linking it using the commands :
nasm -g -f elf64 new3.asm
ld -g new3.o
then i debug it using gdb new3.out
. The gdb version is 7.11.1
the program is below :
section .text
global _start ;must be declared for linker (ld)
_start: ;tells linker entry point
call sum
mov edx,len ;message length
mov ecx,msg ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
sum:
mov eax, ecx
add eax, edx
add eax, '0'
ret
section .data
msg db 'Hello, world!', 0xa ;string to be printed
len equ $ - msg ;length of the string
How i can step inside the _start for debugging and what is the meaning of this?
(gdb) break 3
Note: breakpoints 1, 2 and 3 also set at pc 0x4000b0.
Breakpoint 4 at 0x4000b0: file new3.asm, line 3.
Upvotes: 1
Views: 2034
Reputation: 363882
Use nasm -f elf64 -F dwarf -g new3.asm
to make dwarf debug info, not the default (stabs). (Use nasm -felf64 -y
to see the default). yasm -felf64 -gdwarf2 new3.asm
works, too. (Actually single stepping works even if you leave out -gdwarf2
for yasm: I guess it includes enough by default).
Then gdb will be able to single-step by source lines instead of just by instructions (stepi
). You don't need ld -g
, that doesn't do anything.
You should probably also link with gcc -nostdlib -g new3.o
, instead of ld directly. If you added any dynamic libs to your ld command line, you'd have a broken binary (because ld's default ELF interpreter path isn't useful on modern x86-64 multiarch systems). See Building an executable from asm source that defines _start
vs. main
, static or dynamic.
Also, don't use the int 0x80
32-bit ABI from 64-bit code.
Use stepi
(or si
) to step by instructions instead of by source lines.
Use b *0x4000b0
to set breakpoints based on numeric address. Or use label names, like b _start
to set a breakpoint at the entry point.
See the bottom of the x86 tag wiki for some more tips on debugging asm with gdb.
The first instruction in your file is on line 4, so it's not surprising that b 1
and b 4
both set a breakpoint on the CALL instruction.
b 5
does set a breakpoint on the instruction after CALL. This part does work even when gdb only has STABS debug info (not DWARF or DWARF2), but single-stepping doesn't. IDK why.
(gdb) b _start
Breakpoint 1 at 0x4000b0
(gdb) b 5
Breakpoint 2 at 0x4000b5: file new3.asm, line 5.
(gdb) r
Starting program: /home/peter/src/SO/a.out
Breakpoint 1, 0x00000000004000b0 in _start ()
Upvotes: 3