I'm learning x86-64 assembly on an Oracle Enterprise Linux 7.3 VM. I have a simple program that runs fine outside of gdb but gives a segmentation fault if I set a breakpoint and run the program to it. I've pared it down to a pretty small program but was wondering if I'm doing something wrong or if it is just a gdb bug. Here is the source code of the file ex1.asm:
segment .data
a dd 1
segment .text
global _start
_start:
mov eax,4
ltop:
mov ebx,[a]
; exit with return code 0
mov eax,60
mov edi,0
syscall
end
I assemble, link it, and run it in gdb like this:
yasm -f elf64 -g dwarf2 -l ex1.lst ex1.asm; ld -o ex1.exe ex1.o; gdb ex1.exe
Here is how the gdb session goes:
(gdb) l
1 segment .data
2 a dd 1
3 segment .text
4 global _start
5 _start:
6 mov eax,4
7 ltop:
8 mov ebx,[a]
9 ; exit with return code 0
10 mov eax,60
(gdb) b 8
Breakpoint 1 at 0x4000ba: file ex1.asm, line 8.
(gdb) r
Starting program: /home/bobby/gdbbug/ex1.exe
Program received signal SIGSEGV, Segmentation fault.
ltop () at ex1.asm:6
6 mov eax,4
I've got a simple workaround. I just add an unneeded xor after the _start label.
(gdb) l
1 segment .data
2 a dd 1
3 segment .text
4 global _start
5 _start:
6 xor eax,eax
7 mov eax,4
8 ltop:
9 mov ebx,[a]
10 ; exit with return code 0
(gdb) b 9
Breakpoint 1 at 0x4000b7: file ex1.asm, line 9.
(gdb) r
Starting program: /home/bobby/gdbbug/ex1.exe
Breakpoint 1, ltop () at ex1.asm:9
9 mov ebx,[a]
Removing the ltop label also works but the larger original program that I pared down for this example needs that label so that's not a great workaround.
(gdb) l
1 segment .data
2 a dd 1
3 segment .text
4 global _start
5 _start:
6 mov eax,4
7 ;ltop:
8 mov ebx,[a]
9 ; exit with return code 0
10 mov eax,60
(gdb) b 8
Breakpoint 1 at 0x4000b5: file ex1.asm, line 8.
(gdb) r
Starting program: /home/bobby/gdbbug/ex1.exe
Breakpoint 1, _start () at ex1.asm:8
8 mov ebx,[a]
Kind of odd. Maybe there is something obvious I'm doing that's wrong but it seems more like a gdb bug.
Thanks, Bobby
Additional information based on the comment:
(gdb) l
1 segment .data
2 a dd 1
3 segment .text
4 global _start
5 _start:
6 mov eax,4
7 ltop:
8 mov ebx,[a]
9 ; exit with return code 0
10 mov eax,60
(gdb) b 8
Breakpoint 1 at 0x4000ba: file ex1.asm, line 8.
(gdb) r
Starting program: /home/bobby/gdbbug/ex1.exe
Program received signal SIGSEGV, Segmentation fault.
ltop () at ex1.asm:6
6 mov eax,4
(gdb) q
A debugging session is active.
Inferior 1 [process 4184] will be killed.
Quit anyway? (y or n) y
[bobby@assembly gdbbug]$ objdump -D ex1.exe
ex1.exe: file format elf64-x86-64
Disassembly of section .text:
00000000004000b0 <_start>:
4000b0: b8 04 00 00 00 mov $0x4,%eax
00000000004000b5 <ltop>:
4000b5: 8b 1c 25 c8 00 60 00 mov 0x6000c8,%ebx
4000bc: b8 3c 00 00 00 mov $0x3c,%eax
4000c1: bf 00 00 00 00 mov $0x0,%edi
4000c6: 0f 05 syscall
It seems like the comment might be correct. If I'm reading the dump correctly the move to ebx statement starts at 4000b5 but the breakpoint is set at 4000ba which is inside the bytes for the mov instruction.
This is what happens when I comment out the ltop label:
(gdb) b 8
Breakpoint 1 at 0x4000b5: file ex1.asm, line 8.
(gdb) r
Starting program: /home/bobby/gdbbug/ex1.exe
Breakpoint 1, _start () at ex1.asm:8
8 mov ebx,[a]
The breakpoint is at 0x4000b5 which is what is in the dump:
00000000004000b0 <_start>:
4000b0: b8 04 00 00 00 mov $0x4,%eax
4000b5: 8b 1c 25 c8 00 60 00 mov 0x6000c8,%ebx
Thanks for the reply.
I redid this using nasm using this command line:
nasm -f elf64 ex1.asm -o ex1.o -l ex1.lst -g -F dwarf; ld -o ex1.exe ex1.o; gdb ex1.exe
It worked fine. So, it seems to be an issue with yasm and debugging as the comment suggested.