it-swarm-korea.com

Linux에서 디버깅 목적으로 코어 파일을 보는 방법은 무엇입니까?

프로그램을 디버깅하는 동안 코어 파일의 내용을보고 싶습니다. 코어 파일의 내용을 보려면 어떻게해야합니까?

27
Özzesh

objdump + gdb 실행 가능한 최소 예제

TLDR :

이제 전체 교육 테스트 설정을 위해 :

main.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);
}

컴파일하고 실행하여 코어를 생성하십시오.

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

산출:

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

GDB는 segfault가 발생한 정확한 라인을 가리키며, 이는 디버깅하는 동안 대부분의 사용자가 원하는 것입니다.

gdb -q -nh main.out core

그때:

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

버기 라인 7로 바로 연결됩니다.

Binutils 분석

먼저:

file core

core 파일이 실제로 ELF 파일임을 알려줍니다.

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

그렇기 때문에 일반적인 binutils 도구를 사용하여 더 직접 검사 할 수 있습니다.

ELF standard 을 간단히 살펴보면 실제로 ELF 유형이 전용이라는 것을 알 수 있습니다.

Elf32_Ehd.e_type == ET_CORE

추가 형식 정보는 다음에서 찾을 수 있습니다.

man 5 core

그때:

readelf -Wa core

파일 구조에 대한 힌트를 제공합니다. 메모리는 일반 프로그램 헤더에 포함 된 것으로 보입니다.

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

노트 영역에 메타 데이터가 더 있습니다. 특히 prstatus에는 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는 다음을 사용하여 모든 메모리를 쉽게 덤프 할 수 있습니다.

objdump -s core

포함하는:

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..........

이것은 런에서 stdout 값과 정확히 일치합니다.

Ubuntu 16.04 AMD64, GCC 6.4.0, binutils 2.26.1에서 테스트되었습니다.

gdb는 GNU 디버거이며 코어 파일을 검사하는 데 사용할 수 있습니다. BTW bt (backtrace)는 프로그램 호출 스택을 검사하는 유용한 gdb 명령입니다.

gdb binary-file core-file
15
suspectus

프로그램을 컴파일 할 때 -g 옵션을 사용하십시오.

gcc -g program.c

코어 파일이 생성되면 -g 옵션을 사용하여 gdb를 사용하여 디버그 할 수 있고 디버그 플래그는 활성화되지 않습니다.

4
ganeshredcobra

명령 행 도구를 사용하려면 gdb 를 사용할 수 있습니다.

gdb <program> <core file>

또는

gdb <program> -c <core file>

Gui를 좋아한다면 ddd 를 설치하고 거기서 디버그 할 프로그램과 코어 파일을여십시오.

3
BЈовић