it-swarm.com.de

Wie kann man Kerndateien für Debugging-Zwecke unter Linux anzeigen?

Ich möchte den Inhalt einer Kerndatei beim Debuggen eines Programms anzeigen. Wie kann ich den Inhalt einer Kerndatei anzeigen?

27
Özzesh

objdump + gdb minimales ausführbares Beispiel

TLDR:

Nun zu einem vollständigen Testaufbau für die Ausbildung:

haupt c

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int myfunc(int i) {
    *(int*)(NULL) = i; /* line 7 */
    return i - 1;
}

int main(int argc, char **argv) {
    /* Setup some memory. */
    char data_ptr[] = "string in data segment";
    char *mmap_ptr;
    char *text_ptr = "string in text segment";
    (void)argv;
    mmap_ptr = (char *)malloc(sizeof(data_ptr) + 1);
    strcpy(mmap_ptr, data_ptr);
    mmap_ptr[10] = 'm';
    mmap_ptr[11] = 'm';
    mmap_ptr[12] = 'a';
    mmap_ptr[13] = 'p';
    printf("text addr: %p\n", text_ptr);
    printf("data addr: %p\n", data_ptr);
    printf("mmap addr: %p\n", mmap_ptr);

    /* Call a function to prepare a stack trace. */
    return myfunc(argc);
}

Kompilieren und ausführen, um den Kern zu generieren:

gcc -ggdb3 -std=c99 -Wall -Wextra -pedantic -o main.out main.c
ulimit -c unlimited
rm -f core
./main.out

Ausgabe:

text addr: 0x4007d4
data addr: 0x7ffec6739220
mmap addr: 0x1612010
Segmentation fault (core dumped)

GDB verweist uns auf die genaue Zeile, in der der Segfault aufgetreten ist. Dies möchten die meisten Benutzer beim Debuggen:

gdb -q -nh main.out core

dann:

Reading symbols from main.out...done.
[New LWP 27479]
Core was generated by `./main.out'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000000000400635 in myfunc (i=1) at main.c:7
7           *(int*)(NULL) = i;
(gdb) bt
#0  0x0000000000400635 in myfunc (i=1) at main.c:7
#1  0x000000000040072b in main (argc=1, argv=0x7ffec6739328) at main.c:28

das zeigt uns direkt auf die Buggy-Linie 7.

Binutils-Analyse

Zuerst:

file core

sagt uns, dass die Datei core tatsächlich eine ELF-Datei ist:

core: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, from './main.out'

deshalb können wir es mit den üblichen binutils-Werkzeugen direkter untersuchen.

Ein kurzer Blick auf ELF-Standard zeigt, dass es tatsächlich einen ELF-Typ gibt, der diesem gewidmet ist:

Elf32_Ehd.e_type == ET_CORE

Weitere Formatinformationen finden Sie unter:

man 5 core

Dann:

readelf -Wa core

gibt einige Hinweise zur Dateistruktur. Der Speicher scheint in regulären Programm-Headern enthalten zu sein:

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  NOTE           0x000468 0x0000000000000000 0x0000000000000000 0x000b9c 0x000000     0
  LOAD           0x002000 0x0000000000400000 0x0000000000000000 0x001000 0x001000 R E 0x1000
  LOAD           0x003000 0x0000000000600000 0x0000000000000000 0x001000 0x001000 R   0x1000
  LOAD           0x004000 0x0000000000601000 0x0000000000000000 0x001000 0x001000 RW  0x1000

und es gibt einige weitere Metadaten in einem Notizenbereich, insbesondere prstatus enthält den PC :

Displaying notes found at file offset 0x00000468 with length 0x00000b9c:
  Owner                 Data size       Description
  CORE                 0x00000150       NT_PRSTATUS (prstatus structure)
  CORE                 0x00000088       NT_PRPSINFO (prpsinfo structure)
  CORE                 0x00000080       NT_SIGINFO (siginfo_t data)
  CORE                 0x00000130       NT_AUXV (auxiliary vector)
  CORE                 0x00000246       NT_FILE (mapped files)
    Page size: 4096
                 Start                 End         Page Offset
    0x0000000000400000  0x0000000000401000  0x0000000000000000
        /home/ciro/test/main.out
    0x0000000000600000  0x0000000000601000  0x0000000000000000
        /home/ciro/test/main.out
    0x0000000000601000  0x0000000000602000  0x0000000000000001
        /home/ciro/test/main.out
    0x00007f8d939ee000  0x00007f8d93bae000  0x0000000000000000
        /lib/x86_64-linux-gnu/libc-2.23.so
    0x00007f8d93bae000  0x00007f8d93dae000  0x00000000000001c0
        /lib/x86_64-linux-gnu/libc-2.23.so
    0x00007f8d93dae000  0x00007f8d93db2000  0x00000000000001c0
        /lib/x86_64-linux-gnu/libc-2.23.so
    0x00007f8d93db2000  0x00007f8d93db4000  0x00000000000001c4
        /lib/x86_64-linux-gnu/libc-2.23.so
    0x00007f8d93db8000  0x00007f8d93dde000  0x0000000000000000
        /lib/x86_64-linux-gnu/ld-2.23.so
    0x00007f8d93fdd000  0x00007f8d93fde000  0x0000000000000025
        /lib/x86_64-linux-gnu/ld-2.23.so
    0x00007f8d93fde000  0x00007f8d93fdf000  0x0000000000000026
        /lib/x86_64-linux-gnu/ld-2.23.so
  CORE                 0x00000200       NT_FPREGSET (floating point registers)
  LINUX                0x00000340       NT_X86_XSTATE (x86 XSAVE extended state)

objdump kann problemlos den gesamten Speicher mit folgenden Speicherauszügen sichern:

objdump -s core

was beinhaltet:

Contents of section load1:

 4007d0 01000200 73747269 6e672069 6e207465  ....string in te
 4007e0 78742073 65676d65 6e740074 65787420  xt segment.text 

Contents of section load15:

 7ffec6739220 73747269 6e672069 6e206461 74612073  string in data s
 7ffec6739230 65676d65 6e740000 00a8677b 9c6778cd  egment....g{.gx.

Contents of section load4:

 1612010 73747269 6e672069 6e206d6d 61702073  string in mmap s
 1612020 65676d65 6e740000 11040000 00000000  egment..........

das stimmt genau mit dem Standardwert in unserem Lauf überein.

Getestet in Ubuntu 16.04 AMD64, GCC 6.4.0, binutils 2.26.1.

gdb ist der GNU Debugger, mit dem die Kerndatei untersucht werden kann. BTW bt (backtrace) ist ein nützlicher gdb-Befehl zum Untersuchen des Programmaufrufstapels.

gdb binary-file core-file
15
suspectus

Wenn Sie das Programm kompilieren, verwenden Sie die Option -g

gcc -g program.c

Wenn eine Kerndatei erstellt wird, können Sie mit gdb debuggen, ohne dass die Option -g verwendet wird. Debug-Flags werden nicht aktiviert.

4
ganeshredcobra

Wenn Sie das Befehlszeilentool bevorzugen, können Sie gdb verwenden:

gdb <program> <core file>

oder

gdb <program> -c <core file>

Wenn Sie GUI mögen, installieren Sie ddd und öffnen Sie von dort aus das Programm zum Debuggen und die Kerndatei.

3
BЈовић