14 Debugging Core Files

When the operating system encounters an irrecoverable error running a program, the system creates a file named core and places it in the current directory. The core file is not an executable file; it is a snapshot of the state of your program at the time the error occurred. It allows you to analyze the program at the point it crashed. This chapter describes a technique you can use to debug core files using the Digital Ladebug debugger.

Kernel debugging can be very helpful in analyzing kernel crash dumps. For information on kernel debugging, see Chapter 22.

14.1 Invoking the Debugger on a Core File

You can use the debugger to examine the program information in a core file. Use the following ladebug command syntax to invoke the debugger on a core file:

ladebug  executable_file core_file

Specify the name of the executable file (the program that was running at the time the core file was generated) in addition to the core file.

14.2 Core File Debugging Technique

When debugging a core file, use the debugger to obtain a stack trace and the values of a few variables.

The stack trace lists the functions in your program that were active when the dump occurred. By examining the values of a few program variables along with the stack trace, you should be able to pinpoint the program state and the cause of the core dump. (Core files cannot be executed, and so a rerun, step, cont, etc. will not work until a run is issued.)

In addition, if the program is multithreaded, you can examine the native (that is, kernel-level) thread information with the show thread and thread commands. You can examine the stack trace for a particular thread or all threadswith the where thread command. (See Section 14.3. Also see Chapter 19.)

The program shown in Example 14-1 is almost identical to the program used in Chapter 7 but adds a null pointer reference in the factorial function. This reference causes the program to abort and dump the core when it is executed. The dump command prints the value of the x variable as a null, and the print *x command reveals that you cannot dereference a null pointer.

Example 14-1 Debugging a Core File

% cat testProgram.c
main() {
        int i,f;
        for (i=1 ; i<3 ; i++) {
                f = factorial(i);
                printf("%d! = %d\en",i,f);
        }
}
factorial(i)
int i;
{
int *x;
        x = 0;
        printf("%d",*x);
        if (i<=1)
                return (1);
        else
                return (i * factorial(i-1) );
}

% cc -o testProgram -g testProgram.c
% testProgram
Memory fault - core dumped.

% ladebug testProgram core
Welcome to the Ladebug Debugger Version 4.0
------------------
object file name: testProgram
core file name: core
Reading symbolic information ...done
Core file produced from executable testProgram
Thread terminated at PC 0x120000dc4 by signal SEGV

(ladebug) where
>0  0x120000dc4 in factorial(i=1) testProgram.c:13
#1  0x120000d44 in main() testProgram.c:4

(ladebug) dump
>0  0x120000dc4 in factorial(i=1) testProgram.c:13
printf("%d",*x);

(ladebug) print *x
Cannot dereference 0x0
Error: no value for *x
(ladebug)

14.3 Core Thread Debugging of Native Threads

Ladebug can debug core files generated by multithreaded applications. For this kind of core file debugging, Ladebug sets the $threadlevel variable to native in the following initializations:

Example 14-2 presents an example of core file kernel thread debugging.

Example 14-2 Debugging a Multithreaded Kernel Core File

Welcome to the Ladebug Debugger Version 4.0-10
------------------
object file name: ../bin/c_threadcore
Reading symbolic information ...done
(ladebug) record io out
(ladebug) unload
(ladebug) load ../bin/c_threadcore ../bin/c_threadcore_core
Reading symbolic information ...done
Core file produced from executable c_threadcore
Thread 0xffffffff836934d0 terminated at PC 0x3ff805065c8 by signal SEGV
1
(ladebug) print $threadlevel2
"native"
(ladebug) show thread3
  Thread #  Id                  State
> 1         0xffffffff836934d0  dead
  2         0xffffffff83596120  dead
(ladebug) thread4
Thread 0x1
(ladebug) where5
>0  0x3ff805065c8 in __kill(0xb, 0x2, 0x3, 0x47c18, 0x4, 0x6)
 ../../../../../src/usr/ccs/lib/libc/alpha/kill.s:41
#1  0x3ff8055c560 in exc_raise(0x3ffc01e7e78, 0x0, 0x1, 0x0, 0x309a9a07,
 0xb97c60) ../../../../../src/usr/ccs/lib/DECthreads/COMMON/
 exc_handling.c:649
#2  0x3ff8055c764 in exc_pop_ctx(0x3ffc01e7bd0, 0x0, 0x0, 0x3ff80567b40,
 0x0, 0x0) ../../../../../src/usr/ccs/lib/DECthreads/COMMON/
 exc_handling.c:805
#3  0x3ff8056e374 in cma__thread_base(0x0, 0x0, 0x0, 0x0, 0x0,
 0x1200136e0) ../../../../../src/usr/ccs/lib/DECthreads/COMMON/
 cma_thread.c:1623
(ladebug) thread 26
Thread 0x2
(ladebug) where7
>0  0x3ff8051df04 in msg_receive_trap(0xe56b0, 0x0, 0x3ff804b500c,
 0x100000000000, 0x3ff804b5058, 0x18157f0d0d) /usr/sde/osf1/build/
 goldminos.bld/export/alpha/usr/include/mach/syscall_sw.h:74
#1  0x3ff80514764 in msg_receive(0xe0df0, 0x0, 0x0, 0x240000000000000,
 0x61746164702e, 0x3ff800b9fe0) ../../../../../src/usr/ccs/lib/libmach
 /msg.c:95
#2  0x3ff80574b00 in cma__vp_sleep(0x2801000000, 0x3ff00000001, 0x6,
 0x3ffc00841a0, 0x3ff00000000, 0x3ffc00960c0) ../../../../../src/usr/
 ccs/lib/DECthreads/COMMON/cma_vp.c:1588
#3  0x3ff8055ae7c in cma__dispatch(0x6, 0x3ffc00841a0, 0x3ff00000000,
  0x3ffc00960c0, 0x3ff80554354, 0x3ffc0080468) ../../../../../src/usr/ccs/
 lib/DECthreads/COMMON/cma_dispatch.c:998
#4  0x3ff80554354 in cma__int_wait(0x11ffff428, 0x4ac18, 0x3ffc01de9f8,
 0x70000003, 0x3ff80485192, 0x3ff80089931) ../../../../../src/usr/ccs/
 lib/DECthreads/COMMON/cma_condition.c:2651
#5  0x3ff8056d704 in cma_thread_join(0x11ffff848, 0x11ffffbf0,
 0x11ffffbe8, 0x3ff8056e110, 0x0, 0x3ffc01e3de0) ../../../../../src/
 usr/ccs/lib/DECthreads/COMMON/cma_thread.c:955
#6  0x3ff80563a2c in pthread_join(0x47c18, 0x400000000000002,
 0x11ffffc68, 0x3ffc01de9f8, 0x120013d18, 0x5) ../../../../../src/usr/
 ccs/lib/DECthreads/COMMON/cma_pthread.c:2270
#7  0x120013d70 in main() thread_core.c:92
(ladebug) where thread all8
Stack trace for thread 1
#0  0x3ff805065c8 in __kill(0xb, 0x2, 0x3, 0x47c18, 0x4, 0x6) ../../../../
 ../src/usr/ccs/lib/libc/alpha/kill.s:41
#1  0x3ff8055c560 in exc_raise(0x3ffc01e7e78, 0x0, 0x1, 0x0, 0x309a9a07,
  0xb97c60)
../../../../../src/usr/ccs/lib/DECthreads/COMMON/exc_handling.c:649
#2  0x3ff8055c764 in exc_pop_ctx(0x3ffc01e7bd0, 0x0, 0x0, 0x3ff80567b40,
 0x0, 0x0) ../../../../../src/usr/ccs/lib/DECthreads/COMMON/
 exc_handling.c:805
#3  0x3ff8056e374 in cma__thread_base(0x0, 0x0, 0x0, 0x0, 0x0,
 0x1200136e0) ../../../../../src/usr/ccs/lib/DECthreads/
 COMMON/cma_thread.c:1623
Stack trace for thread 2
>0  0x3ff8051df04 in msg_receive_trap(0xe56b0, 0x0, 0x3ff804b500c,
 0x100000000000, 0x3ff804b5058, 0x18157f0d0d) /usr/sde/osf1/build/
 goldminos.bld/export/alpha/usr/include/mach/syscall_sw.h:74
#1  0x3ff80514764 in msg_receive(0xe0df0, 0x0, 0x0, 0x240000000000000,
 0x61746164702e, 0x3ff800b9fe0) ../../../../../src/usr/ccs/lib/libmach/
 msg.c:95
#2  0x3ff80574b00 in cma__vp_sleep(0x2801000000, 0x3ff00000001, 0x6,
 0x3ffc00841a0, 0x3ff00000000, 0x3ffc00960c0) ../../../../../src/usr/
 ccs/lib/DECthreads/COMMON/cma_vp.c:1588
#3  0x3ff8055ae7c in cma__dispatch(0x6, 0x3ffc00841a0, 0x3ff00000000,
 0x3ffc00960c0, 0x3ff80554354, 0x3ffc0080468) ../../../../../src/usr/
 ccs/lib/DECthreads/COMMON/cma_dispatch.c:998
#4  0x3ff80554354 in cma__int_wait(0x11ffff428, 0x4ac18, 0x3ffc01de9f8,
 0x70000003, 0x3ff80485192, 0x3ff80089931) ../../../../../src/usr/ccs/
 lib/DECthreads/COMMON/cma_condition.c:2651
#5  0x3ff8056d704 in cma_thread_join(0x11ffff848, 0x11ffffbf0,
 0x11ffffbe8, 0x3ff8056e110, 0x0, 0x3ffc01e3de0)
../../../../../src/usr/ccs/lib
#6  0x3ff80563a2c in pthread_join(0x47c18, 0x400000000000002,
 0x11ffffc68, 0x3ffc01de9f8, 0x120013d18, 0x5) ../../../../../src/usr/
#7  0x120013d70 in main() thread_core.c:92

(ladebug) thread 19
Thread 0x1
(ladebug) printregs10
$r0  [$v0]  = 0                         $r1  [$t0]  = 0
$r2  [$t1]  = 4396974517024             $r3  [$t2]  = 320024
$r4  [$t3]  = 4396974517024             $r5  [$t4]  = 0
$r6  [$t5]  = 0                         $r7  [$t6]  = 130
$r8  [$t7]  = 0                         $r9  [$s0]  = 2
$r10 [$s1]  = 2                         $r11 [$s2]  = 0
$r12 [$s3]  = 0                         $r13 [$s4]  = 0
$r14 [$s5]  = 0                         $r15 [$s6]  = 0
$r16 [$a0]  = 28613                     $r17 [$a1]  = 11
$r18 [$a2]  = 4396974766704             $r19 [$a3]  = 0
$r20 [$a4]  = 0                         $r21 [$a5]  = 4
$r22 [$t8]  = 3                         $r23 [$t9]  = 0
$r24 [$t10] = 3                         $r25 [$t11] = 0
$r26 [$ra]  = 4395904648544             $r27 [$t12] = 4395904749552
$r28 [$at]  = -1                        $r29 [$gp]  = 4396974751200
$r30 [$sp]  = 4396974766800             $r31 [$zero]= 0
$f0         = 0                         $f1         = 0
$f2         = 0                         $f3         = 0
$f4         = 0                         $f5         = 0
$f6         = 0                         $f7         = 0
$f8         = 0                         $f9         = 0
$f10        = 0                         $f11        = 0
$f12        = 0                         $f13        = 0
$f14        = 0                         $f15        = 0
$f16        = 0                         $f17        = 0
$f18        = 0                         $f19        = 0
$f20        = 0                         $f21        = 0
$f22        = 0                         $f23        = 0
$f24        = 0                         $f25        = 0
$f26        = 0                         $f27        = 0
$f28        = 0                         $f29        = 0
$f30        = 0                         $f31        = 0
$pc         = 0x3ff805065c8
(ladebug) thread 2
Thread 0x2
(ladebug) printregs
$r0  [$v0]  = -207                      $r1  [$t0]  = 0
$r2  [$t1]  = 0                         $r3  [$t2]  = 0
$r4  [$t3]  = 0                         $r5  [$t4]  = 0
$r6  [$t5]  = 1                         $r7  [$t6]  = 1
$r8  [$t7]  = 0                         $r9  [$s0]  = 4831834496
$r10 [$s1]  = 0                         $r11 [$s2]  = 4396974730048
$r12 [$s3]  = 0                         $r13 [$s4]  = 0
$r14 [$s5]  = 162129586585337856        $r15 [$s6]  = 0
$r16 [$a0]  = 4831834496                $r17 [$a1]  = 0
$r18 [$a2]  = 40                        $r19 [$a3]  = 6
$r20 [$a4]  = 0                         $r21 [$a5]  = 6
$r22 [$t8]  = 4                         $r23 [$t9]  = 2
$r24 [$t10] = 1                         $r25 [$t11] = 0
$r26 [$ra]  = 4395904354148             $r27 [$t12] = 4395904050272
$r28 [$at]  = 293938                    $r29 [$gp]  = 4396974651024
$r30 [$sp]  = 4831834336                $r31 [$zero]= 0
$f0         = 0                         $f1         = 0
$f2         = 0                         $f3         = 0
$f4         = 0                         $f5         = 0
$f6         = 0                         $f7         = 0
$f8         = 0                         $f9         = 0
$f10        = 3.237908616585193e-319    $f11        = 65536
$f12        = 0                         $f13        = 0
$f14        = 1.016984725399622e-319    $f15        = 20584
$f16        = 0                         $f17        = 0
$f18        = 0                         $f19        = 0
$f20        = 0                         $f21        = 0
$f22        = 3.237908616585193e-319    $f23        = 65536
$f24        = 0                         $f25        = 0
$f26        = 0                         $f27        = 0
$f28        = 0                         $f29        = 0
$f30        = 0                         $f31        = 0
$pc         = 0x3ff8051df04
(ladebug)

  1. When debugging a multithreaded core file, Ladebug shows the kernel thread ID of the of the thread that incurred the fault.
    Note
    For a single thread core file, Ladebug will not show the kernel thread ID.

  2. The $threadlevel is set to native and you can begin core file kernel thread debugging.

  3. Ladebug provides a list of threads.

  4. Ladebug displays the current thread context.

  5. Ladebug provides a stack trace of the current thread.

  6. Ladebug sets the thread context to thread #2.

  7. Ladebug provides the stack trace of the new current thread.

  8. When specifying the where thread all , Ladebug shows the stack trace for all threads. Notice that it labels the stack trace for each thread.

  9. When specifying the thread command with the thread ID, Ladebug changes the thread context to that thread (in this case, thread 1).

  10. The printregs command asks Ladebug to show the register contents within the current thread context.