3

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.

Bobby Durrett
  • 1,223
  • 12
  • 19
  • 4
    My best guess is that YASM has a bug in the debug data and it hasn't correctly identified the address of the insruction at line 8. I suspect if you do an `objdump -D ex1.exe` you'd probably discover that the address listed here (0x4000b5) in `0x4000b5: file ex1.asm, line 8` is not actually the address of the instruction on line 8 that it is in fact an address in the middle of an instruction. – Michael Petch Feb 07 '17 at 00:36

0 Answers0