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);
 
axis/gdb-debug-core-dump.txt · Last modified: 2007/03/05 15:50 by jesper
 
All text is available under the terms of the GNU Free Documentation License (see Copyrights for details).