This is the mail archive of the
gdb@sourceware.org
mailing list for the GDB project.
Help understanding x86 assembly debugging with GDB
- From: Peter Watkins <peter_watkins at mentor dot com>
- To: gdb at sources dot redhat dot com
- Date: Fri, 21 Jan 2011 11:31:04 -0800
- Subject: 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