This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Help understanding x86 assembly debugging with GDB


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]