Coredump contains the recorded state of working memory of a program when it crashed or terminated abnormally. This becomes very essential when you are program is complex and crashed half way through the execution and you have no idea what caused the crash.
In Android, when an application crashes, it prints out the stack trace along with the last known address which resulted in the crash into the Android logcat logs. In Linux this is not enabled by default, this post will help you to enable the core dump on Linux.
We will use this simple application to cause a crash
#include <stdio.h>
int main() {
int a = 5, b = 0;
int c = a / b;
printf ("Value of c is %d", c);
return 0;
}
Compile this source code using gcc –
$ gcc -g main.c
The g flag to gcc will enable the debug symbols, without this the coredump file will not be very useful. You can also use -ggdb option to produce debug symbols that gdb can use. More info debuggion options available on gcc can found here.
Run the program –
$ ./a.out
Floating point exception.
Okay, so our program crashes as expected. But the message “Floating point exception” is not very helpful in telling us where exactly this problem happened and also note that there was no message about the core being dumped.
Let’s turn on the coredump, using the ulimit cmd we can check the size of core file size.
$ ulimit -a
core file size (blocks, -c) 0
…
Increase the size to unlimited
$ ulimit –c unlimited
Check whether the change has taken effect –
$ulimit –a
core file size (blocks, -c) unlimited
…
Now we need to ensure that coredump is redirected to a file instead of someplace else. To check what is your current setting run–
$ cat /proc/sys/kernel/core_pattern
|/usr/share/apport/apport %p %s %c
The “|” indicates to the kernel that the rest of the pattern is a command to be run. Save this command if you want you restore your default settings. To redirect it to a file in the current working directory, we will overwrite the pattern with –
$ echo "core.%e.%p" > /proc/sys/kernel/core_pattern
This will create a file called core.<output_file_name>.<process_id> in the current working directory.
Now that everything is in place, let’s run the program again –
$./a.out
Floating point exception (core dumped)
$ ls
a.out core.a.out.3244 main.c
The core dump has been generated. Now let’s use gdb to look into the coredump file. Start gdb for the coredump file
$ gdb <path_to_bin> <path_to_coredump_file>
...
Core was generated by `./a.out'.
Program terminated with signal SIGFPE, Arithmetic exception.
#0 0x0000000000400547 in main () at main.c:5
5 int c = a / b;
By default, it shows the last executed statement and you can run other gdb commands like –
(gdb) bt
#0 0x0000000000400547 in main () at main.c:5
- list – shows the source code, shows 10 lines by default
(gdb) list
1 #include <stdio.h>
2
3 int main() {
4 int a = 5, b = 0;
5 int c = a / b;
6 printf("Value of c is %d", c);
7 return 0;
8 }
- info locals – Values for local variables
(gdb) info locals
a = 5
b = 0
c = 0
- print <variable_name> – Prints the value of the variable
(gdb) print a
$1 = 5
Those were the few commands that were useful to me, there are more commands that you can use for GDB and you can find them on the internet or typing help in gdb console.