Well, I will take a simple example as follows.
#include <stdio.h>
void main()
{
int *p=NULL;
printf("I Should be coring now");
printf("%d", *p);
}
As you can probably guess, there is problem in printf("%d", *p);
, however it would not be shown clearly in gdb's output.
bash-4.1$ gdb test
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.SCLC6_4.1.R1.1.1)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /tmp/test...done.
(gdb) run
Starting program: /tmp/test
Program received signal SIGSEGV, Segmentation fault.
0x080483e6 in main () at test.c:7
7 printf("%d", *p);
In this trivial case, it is quite straight-forward. But for name sake, let us assume that, we need more information. So let us now try to find the pc
while the SIGSEGV
had occured. The pc
effectively says that, while executing that particular instruction, core occured.
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.107.SCLC6_4.5.R1.1.1.i686
(gdb) info registers
eax 0x0 0
ecx 0xbffff6f8 -1073744136
edx 0x2c5340 2904896
ebx 0x2c3ff4 2899956
esp 0xbffff710 0xbffff710
ebp 0xbffff738 0xbffff738
esi 0x0 0
edi 0x0 0
eip 0x80483e6 0x80483e6 <main+34>
eflags 0x10292 [ AF SF IF RF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
So in our case, the pc
is eip 0x80483e6 0x80483e6 <main+34>
It is now clear that, while executing the instruction that is at offset 34 from main, the core had occured. So now, the important issue is to map this instruction with highlevel language. For which use the disasm
command as follows.
(gdb) disas /m main
Dump of assembler code for function main:
4 {
0x080483c4 <+0>: push %ebp
0x080483c5 <+1>: mov %esp,%ebp
0x080483c7 <+3>: and $0xfffffff0,%esp
0x080483ca <+6>: sub $0x20,%esp
5 int *p=NULL;
0x080483cd <+9>: movl $0x0,0x1c(%esp)
6 printf("I Should be coring now");
0x080483d5 <+17>: mov $0x80484c4,%eax
0x080483da <+22>: mov %eax,(%esp)
0x080483dd <+25>: call 0x80482f4 <printf@plt>
7 printf("%d", *p);
0x080483e2 <+30>: mov 0x1c(%esp),%eax
=> 0x080483e6 <+34>: mov (%eax),%edx
0x080483e8 <+36>: mov $0x80484db,%eax
0x080483ed <+41>: mov %edx,0x4(%esp)
0x080483f1 <+45>: mov %eax,(%esp)
0x080483f4 <+48>: call 0x80482f4 <printf@plt>
8 }
0x080483f9 <+53>: leave
0x080483fa <+54>: ret
End of assembler dump.
(gdb)
Though this might not work out of the box , it will give close to 90% accuracy, as far as I have seen from my experience.