|
Debugging Core Dumps
The CRIS port of the Linux kernel can dump
core for a user mode application. gdb-cris can then read this
core file, to allow investigating the cause for the core
dump. This section assumes that you have read the
section on debugging shared
libraries.
Setting the Core File Size
To get a core dump you need to change the max core file
size, because it's by default 0. Some shells have a built-in command which lets you set various
resource limits for the processes started by the shell, like
the core file size, called ulimit. Here's an example of how it
might look:
[root@AxisProduct
/]4624# ulimit -a
time(seconds)
4294967295
file(blocks)
8388607
data(kbytes)
4194303
stack(kbytes)
8192
coredump(blocks)
0
memory(kbytes)
4194303
locked memory(kbytes) 4194303
process(processes)
128
nofiles(descriptors) 1024
Notice
that the "coredump" line says 0 blocks. Change
it using 'ulimit -c':
[root@AxisProduct
/]4624# ulimit -c unlimited
Now check the new limit:
[root@AxisProduct
/]4624# ulimit -a
time(seconds)
4294967295
file(blocks)
8388607
data(kbytes)
4194303
stack(kbytes)
8192
coredump(blocks)
unlimited
memory(kbytes)
4194303
locked memory(kbytes) 4194303
process(processes)
128
nofiles(descriptors) 1024
You can also use the setrlimit
function in your application to set the allowed core file size
(see 'man setrlimit').
Running the Program
You have to run the program from a writeable directory,
such as /tmp, to get a core dump. Many applications reside in
/bin, which is read-only.
Analyzing a Core Dump
Segmentation faults could happen inside your own
application, or in a shared library. Since the latter
case is trickier, it's what we'll demonstrate. Using the 'ulimit
-c' method to set the core file size, here is a small example
program that will dump core (since we're passing an integer as
a char * to printf):
#include <stdio.h>
int main ()
{
printf ("%s", 1);
return 0;
}
Putting the program in /tmp and running it produces:
[root@AxisProduct /var/tmp]9355# ./coredumper
Segmentation fault - core dumped
Now there's a file called core in /tmp. Transfer it to your
host via ftp. Here's an example session of how things might
look in gdb-cris:
(gdb)
file coredumper
Reading symbols from coredumper...done.
(gdb) core-file core
Core was generated by `./coredumper'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /usr/local/cris/r59/cris-axis-linux-gnu/lib/libc.so.6...done.
Loaded symbols for /usr/local/cris/r59/cris-axis-linux-gnu/lib/libc.so.6
Reading symbols from /usr/local/cris/r59/cris-axis-linux-gnu/lib/ld.so.1...done.
Loaded symbols for /usr/local/cris/r59/cris-axis-linux-gnu/lib/ld.so.1
#0 0x355c274c in
strlen (str=0x1 <Address 0x1 out of bounds>)
at
../sysdeps/generic/strlen.c:41
41
if (*char_ptr == '\0')
The cause for the segmentation fault is obvious. str = 0x1,
and strlen tries to dereference this pointer. (If you didn't
set your shared library and source search paths you'd get some
warnings at this point.) Since we don't expect strlen to have
done anything wrong, we'd like to know where the call that
eventually led to strlen originates from. So, we backtrace:
(gdb)
backtrace
#0 0x355c274c in
strlen (str=0x1 <Address 0x1 out of bounds>)
at ../sysdeps/generic/strlen.c:41
#1 0x355a2786 in
_IO_vfprintf (s=0x3562fe0c, format=0x8039c "%s",
ap=0x9ffffe48)
at vfprintf.c:1524
#2 0x355a8820 in printf (format=0x1 <Address 0x1 out of
bounds>)
at
printf.c:33
#3 0x00080344 in
main () at coredumper.c:5
Selecting
the outermost frame shows us the cause for the segmentation
fault:
(gdb)
frame 3
#3 0x00080344
in main () at coredumper.c:5
5
printf ("%s", 1);
|