First create a .cpp file with the content of the sample file crash.cpp
(You can copy it to another .cpp file or downoad it). You can find the file stored here.
The crash.cpp
program which generate a core dump.
Frist , to enable debugging, the program must be compiled with the -g
option( -g
option is used to request debugging information).
root@erlerobot:~/GDB# g++ -g crash.cpp -o crash
root@erlerobot:~/GDB# ls
a.out crash crash.cpp hello.cpp
root@erlerobot:~/GDB#
Now, when run this program on your linux machine, it produces the result:
root@erlerobot:~/GDB# ./crash
Floating point exception
Now to debug the problem, start gdb debugger at command prompt:
root@erlerobot:~/GDB# gdb crash
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 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 "arm-linux-gnueabihf".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /root/GDB/crash...done.
(gdb)
(gdb)
The following steps are:
(gdb) r
Program received signal SIGFPE, Arithmetic exception.
0x08048681 in divint(int, int) (a=3, b=0) at crash.cc:21
21 return a / b;
# 'r' runs the program inside the debugger
# In this case the program crashed and gdb prints out some
# relevant information. In particular, it crashed trying
# to execute line 21 of crash.cc. The function parameters
# 'a' and 'b' had values 3 and 0 respectively.
(gdb) l
# l is short for 'list'. Useful for seeing the context of
# the crash, lists code lines near around 21 of crash.cc
(gdb) where
#0 0x08048681 in divint(int, int) (a=3, b=0) at crash.cc:21
#1 0x08048654 in main () at crash.cc:13
# Equivalent to 'bt' or backtrace. Produces what is known
# as a 'stack trace'. Read this as follows: The crash occurred
# in the function divint at line 21 of crash.cc. This, in turn,
# was called from the function main at line 13 of crash.cc
(gdb) up
# Move from the default level '0' of the stack trace up one level
# to level 1.
(gdb) list
# list now lists the code lines near line 13 of crash.cc
(gdb) p x
# print the value of the local (to main) variable x
In this example, it is fairly obvious that the crash occurs because of the attempt to divide an integer by 0.
That's one of he reasonns why gdb is so useful, we are able to identify errors using GDB.
Let us write another program which will cause a core dump due to non initialized memory:crash1.cpp
.Find the complete file here
When compiling and running it, the following error is produced:
root@erlerobot:~/GDB# g++ -g crash1.cpp -o crash1
root@erlerobot:~/GDB# ls
a.out crash crash.cpp crash1 crash1.cpp hello.cpp
root@erlerobot:~/GDB# ./crash1
10
Segmentation fault
root@erlerobot:~/GDB#
Now we want to identify the error:
root@erlerobot:~/GDB# gdb crash1
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 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 "arm-linux-gnueabihf".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /root/GDB/crash1...done.
(gdb) r
Starting program: /root/GDB/crash1
10
Program received signal SIGSEGV, Segmentation fault.
0x0000867a in setint (ip=0x0, i=10) at crash1.cpp:16
16 *ip = i;
(gdb) where
#0 0x0000867a in setint (ip=0x0, i=10) at crash1.cpp:16
#1 0x0000863c in main () at crash1.cpp:11
Unfortunately, the program did not crash in either of the user-defined functions main or setint, so there is no useful trace or local variable information. In this case, it may be more useful to single-step through the program.
(gdb) b main
Breakpoint 1 at 0x8606: file crash1.cpp, line 8.
# Set a breakpoint at the beginning of the function main.
(gdb)
(gdb) r
# Run the program, but break immediately due to the breakpoint.
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/GDB/crash1
Breakpoint 1, main () at crash1.cpp:8
8 setint(&a, 10);
(gdb) n
# n = next, runs one line of the program.
9 cout << a << endl;
(gdb) n
10
11 setint(b, 10);
(gdb) s
# s = step, is like next, but it will step into functions.
# In this case the function stepped into is setint.
setint (ip=0x0, i=10) at crash1.cpp:16
16 *ip = i;
(gdb) p ip
# p print the value on the screen.
$1 = (int *) 0x0
(gdb) p *ip
Cannot access memory at address 0x0
(gdb)
The value of *ip
is the value of the integer pointed to by ip
. In this case it is an unusual value and is strong evidence that there is a problem. The problem in this case is that the pointer was never properly initialized, so it is pointing to some random area in memory. By pure luck, the process of assiging a value to *ip
does not crash the program, but it creates some problem that crashes the program when it finishes.