Help understanding x86 assembly debugging with GDB

Peter Watkins peter_watkins@mentor.com
Fri Jan 21 19:31:00 GMT 2011


I'm debugging a proprietary shared library. I don't have the source 
code, but it was compiled with debug symbols (yay!). I wrote a simple 
program that uses this shared library, and the program intermittently 
crashes with a segmentation fault inside the shared library's code. 
Here's the frame info where it crashes:
(gdb) info frame
Stack level 0, frame at 0x40a31bf0:
  rip = 0x2af5da1b31b2 in getNextLineD_ (../lib.words.c:785); saved rip 
0x2af5da1b35de
  called by frame at 0x40a31c30
  source language c.
  Arglist at 0x40a31be0, args: fp=0x181a3c70, LineCount=0x40a31e5c, 
confFormat=1
  Locals at 0x40a31be0, Previous frame's sp is 0x40a31bf0
  Saved registers:
   rbp at 0x40a31be0, rip at 0x40a31be8

The assembly for the end of the getNextLineD_ function is as follows:
0x00002af5da1b319f <getNextLineD_+762>:    lea    -0x1c(%rbp),%rax
0x00002af5da1b31a3 <getNextLineD_+766>:    incl   (%rax)
0x00002af5da1b31a5 <getNextLineD_+768>:    mov    -0x1c(%rbp),%eax
0x00002af5da1b31a8 <getNextLineD_+771>:    movslq %eax,%rdx
0x00002af5da1b31ab <getNextLineD_+774>:    mov    
0x21a17e(%rip),%rax        # 0x2af5da3cd330 <line.7>
0x00002af5da1b31b2 <getNextLineD_+781>:    movb   $0x0,(%rdx,%rax,1)
0x00002af5da1b31b6 <getNextLineD_+785>:    mov    
0x21a173(%rip),%rax        # 0x2af5da3cd330 <line.7>
0x00002af5da1b31bd <getNextLineD_+792>:    mov    %rax,-0x40(%rbp)
0x00002af5da1b31c1 <getNextLineD_+796>:    jmp    0x2af5da1b31cb 
<getNextLineD_+806>
0x00002af5da1b31c3 <getNextLineD_+798>:    movq   $0x0,-0x40(%rbp)
0x00002af5da1b31cb <getNextLineD_+806>:    mov    -0x40(%rbp),%rax
0x00002af5da1b31cf <getNextLineD_+810>:    leaveq
0x00002af5da1b31d0 <getNextLineD_+811>:    retq

Some of the pertinent registers are:
(gdb) info reg
rax            0x0    0
rbx            0x0    0
rcx            0x248    584
rdx            0x1    1
.
.
.
rip            0x2af5da1b31b2    0x2af5da1b31b2 <getNextLineD_+781>


Looking at the present instruction...
0x00002af5da1b31b2 <getNextLineD_+781>:    movb   $0x0,(%rdx,%rax,1)
...the segmentation fault is obvious to me: I'm trying to store the 
immediate value 0x0 into memory at address 0x1 (0x1 + 0x0 * 1). Memory 
at 0x1 isn't accessible to my program, so it segfaults.

What isn't obvious to me is how %rax got its zero value. In the 
instruction preceding...
0x00002af5da1b31ab <getNextLineD_+774>:    mov    
0x21a17e(%rip),%rax        # 0x2af5da3cd330 <line.7>
...I store the value at memory address 0x2af5da3cd330 into %rax. This is 
the global variable, "line". "line" is a pointer to a character:
(gdb) whatis line
type = char *

Its value is:
(gdb) p /a line
$2 = 0x181a3eb0

The character at this address is:
(gdb) p line[0]
$3 = 76 'L'

So, in my mind, 0x181a3eb0 should have been stored into %rax, not 0x0. 
In fact, when I run my program through gdb (and it doesn't crash), this 
is exactly what happens--%rax gets a real address, not 0x0. I'm new to 
debugging in assembly, so perhaps there's something I'm not 
understanding. Anyone know why %rax got its 0x0 value?

Thanks,

Peter



More information about the Gdb mailing list