Linux에서 세그멘테이션 오류로 코어 덤프를 생성하는 방법은 무엇입니까?


답변:


249

사용중인 쉘에 따라 다릅니다. bash를 사용하는 경우 ulimit 명령은 코어 실행 여부와 같은 프로그램 실행과 관련된 여러 설정을 제어합니다. 입력하면

ulimit -c unlimited

그러면 프로그램이 어떤 크기의 코어도 덤프 할 수 있다고 bash에 알릴 것입니다. 원하는 경우 무제한 대신 52M과 같은 크기를 지정할 수 있지만 실제로는 코어 파일의 크기가 결코 문제가되지 않으므로 필요하지 않습니다.

tcsh에서는 다음을 입력합니다

limit coredumpsize unlimited

21
@lzprgmr : 명확히하기 위해 : 기본적으로 코어 덤프가 생성되지 않는 이유는 한계가 설정되지 않았거나 0으로 설정되어 코어가 덤프되지 않기 때문입니다. 제한을 무제한으로 설정하면 코어 덤프를 항상 생성 할 수 있습니다.
Eli Courtwright

6
링크 는 더 깊이 들어가고 리눅스에서 코어 덤프 생성을 가능하게하는 더 많은 옵션을 제공합니다. 유일한 단점은 일부 명령 / 설정이 설명 할 수 없다는 것입니다.
살사

6
bash 4.1.2 (1)에서 52M과 같은 릴리스 제한을 지정할 수 없으므로 잘못된 숫자 오류 메시지가 나타납니다. 매뉴얼 페이지에는 "값이 1024 바이트 단위로 증가합니다"라고 알려줍니다.
a1an

4
글쎄, "작은"OpenGL 프로젝트가 있었는데, 한때 이상한 일을했고 X 서버 충돌을 일으켰습니다. 다시 로그인하면 귀여운 17GB 코어 파일 (25GB 파티션)을 보았습니다. 핵심 파일의 크기를 제한적으로 유지하는 것이 좋습니다 :)
IceCool

1
@PolarisUser : 파티션을 먹지 않으려면 1 공연과 같은 한도를 설정하는 것이 좋습니다. 남은 하드 드라이브 공간을 모두 사용하겠다고 위협하지 않으면 서 합리적인 코어 덤프를 처리 할 수있을만큼 커야합니다.
Eli Courtwright

60

위에서 설명한 것처럼 여기서 실제로 묻는 질문은 활성화되지 않은 시스템에서 코어 덤프를 활성화하는 방법입니다. 그 질문에 대한 답이 여기에 있습니다.

중단 된 프로세스에 대한 코어 덤프를 생성하는 방법을 배우려고 여기에 온다면 그 대답은

gcore <pid>

시스템에서 gcore를 사용할 수없는 경우

kill -ABRT <pid>

kill -SEGV를 사용하지 마십시오. 종종 신호 처리기를 호출하여 걸린 프로세스를 진단하기 어렵게 만듭니다.


나는 그것이 훨씬 더 가능성이 그 생각 -ABRT보다 신호 처리기를 호출합니다 -SEGV중지 판단이 segfault의 이상 복구 할 가능성이 더 높습니다로. segfault를 처리하는 경우 일반적으로 처리기가 종료 되 자마자 다시 트리거됩니다. 코어 덤프 생성을위한 더 나은 신호 선택은입니다 -QUIT.
celticminstrel

32

코어 덤프가 생성되는 위치를 확인하려면 다음을 실행하십시오.

sysctl kernel.core_pattern

또는:

cat /proc/sys/kernel/core_pattern

%e프로세스 이름과 %t시스템 시간 은 어디에 있습니까 ? 에서 변경 /etc/sysctl.conf하고 다시로드 할 수 있습니다 sysctl -p.

코어 파일이 생성되지 않은 경우 ( sleep 10 &및로 테스트 killall -SIGSEGV sleep) 다음으로 한계를 확인하십시오 ulimit -a.

코어 파일 크기가 제한되어 있으면 다음을 실행하십시오.

ulimit -c unlimited

무제한으로 만들 수 있습니다.

그런 다음 코어 덤핑에 성공하면 다음과 같이 세그먼테이션 오류 표시 후 "(코어 덤프)"가 표시됩니다.

분할 오류 : 11 (코어 덤프)

참조 : 코어 덤프 -하지만 핵심 파일이 현재 디렉토리에 있지?


우분투

우분투에서 코어 덤프는 Apport에 의해 처리되며 에 위치 할 수 있습니다 /var/crash/. 그러나 안정적인 릴리스에서는 기본적으로 비활성화되어 있습니다.

자세한 내용 은 Ubuntu에서 코어 덤프를 어디서 찾을 수 있습니까? 를 확인하십시오. .

맥 OS

macOS의 경우 : Mac OS X에서 코어 덤프를 생성하는 방법은 무엇입니까?


3
우분투의 경우, 정상적인 동작으로 빠르게 되돌리려면 (현재 디렉토리에 코어 파일 덤핑) "sudo service apport stop"으로 apport 서비스를 중지하십시오. 또한 docker 내에서 실행중인 경우 해당 설정은 컨테이너가 아닌 호스트 시스템에서 제어됩니다.
Digicrat

26

내가 마지막에 한 것은 충돌하기 전에 프로세스에 gdb를 첨부 한 다음 segfault를 얻었을 때 나는 generate-core-file명령을 실행했다 . 이로 인해 코어 덤프가 생성되었습니다.


프로세스에 gdb를 어떻게 첨부 했습니까?
Chani

6
Ritwik G에 응답하려면 프로세스를 gdb에 첨부하려면 gdb를 시작하고 'attach <pid>'를 입력하십시오. 여기서 <pid>는 첨부 할 프로세스의 pid 번호입니다.
Jean-Dominique Frattini 2016 년

(약칭 ge)
user202729 2016 년

새로운 질문이 있으면 의견을 묻는 대신 새로운 질문 을해야합니다 .
user202729 2016 년

이상한 것은이 이미 설정되어 있지 않은 ulimit -c으로 unlimited하지만, 코어 파일이 더 만들어 잠잠되면, generate-core-fileGDB 세션에서 파일 덕분에 코어 파일을 생성한다.
CodyChan

19

어쩌면 이런 식으로 할 수 있습니다.이 프로그램은 세그먼테이션 오류를 포착하고 디버거 (이것은 아래에서 사용되는 원래 코드 AIX임)에 쉘을 트랩하는 방법을 보여주고 스택 추적을 세그먼테이션 오류 지점까지 인쇄합니다. Linux의 경우 sprintf사용할 변수 를 변경해야합니다 gdb.

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <stdarg.h>

static void signal_handler(int);
static void dumpstack(void);
static void cleanup(void);
void init_signals(void);
void panic(const char *, ...);

struct sigaction sigact;
char *progname;

int main(int argc, char **argv) {
    char *s;
    progname = *(argv);
    atexit(cleanup);
    init_signals();
    printf("About to seg fault by assigning zero to *s\n");
    *s = 0;
    sigemptyset(&sigact.sa_mask);
    return 0;
}

void init_signals(void) {
    sigact.sa_handler = signal_handler;
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    sigaction(SIGINT, &sigact, (struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask, SIGSEGV);
    sigaction(SIGSEGV, &sigact, (struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask, SIGBUS);
    sigaction(SIGBUS, &sigact, (struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask, SIGQUIT);
    sigaction(SIGQUIT, &sigact, (struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask, SIGHUP);
    sigaction(SIGHUP, &sigact, (struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask, SIGKILL);
    sigaction(SIGKILL, &sigact, (struct sigaction *)NULL);
}

static void signal_handler(int sig) {
    if (sig == SIGHUP) panic("FATAL: Program hanged up\n");
    if (sig == SIGSEGV || sig == SIGBUS){
        dumpstack();
        panic("FATAL: %s Fault. Logged StackTrace\n", (sig == SIGSEGV) ? "Segmentation" : ((sig == SIGBUS) ? "Bus" : "Unknown"));
    }
    if (sig == SIGQUIT) panic("QUIT signal ended program\n");
    if (sig == SIGKILL) panic("KILL signal ended program\n");
    if (sig == SIGINT) ;
}

void panic(const char *fmt, ...) {
    char buf[50];
    va_list argptr;
    va_start(argptr, fmt);
    vsprintf(buf, fmt, argptr);
    va_end(argptr);
    fprintf(stderr, buf);
    exit(-1);
}

static void dumpstack(void) {
    /* Got this routine from http://www.whitefang.com/unix/faq_toc.html
    ** Section 6.5. Modified to redirect to file to prevent clutter
    */
    /* This needs to be changed... */
    char dbx[160];

    sprintf(dbx, "echo 'where\ndetach' | dbx -a %d > %s.dump", getpid(), progname);
    /* Change the dbx to gdb */

    system(dbx);
    return;
}

void cleanup(void) {
    sigemptyset(&sigact.sa_mask);
    /* Do any cleaning up chores here */
}

이 블로그의 여기 에 표시된대로 gdb가 코어를 덤프하도록 매개 변수를 추가해야 할 수도 있습니다 .


16

코어 덤프 생성에 영향을 줄 수있는 것들이 더 있습니다. 나는 이것들을 만났다 :

  • 덤프 디렉토리는 쓰기 가능해야합니다. 기본적으로 이것은 프로세스의 현재 디렉토리이지만 설정으로 변경 될 수 있습니다 /proc/sys/kernel/core_pattern.
  • 일부 조건에서 커널 값 /proc/sys/fs/suid_dumpable은 코어 생성을 방해 할 수 있습니다.

매뉴얼 페이지에 설명 된 생성을 방해 할 수있는 상황이 더 있습니다 man core.


9

코어 덤프를 활성화하려면 다음을 수행하십시오.

  1. 에서 /etc/profile코멘트 라인 :

    # ulimit -S -c 0 > /dev/null 2>&1
  2. 에서 /etc/security/limits.conf라인 밖으로 코멘트 :

    *               soft    core            0
  3. cmd를 실행하고 cmd limit coredumpsize unlimited로 확인하십시오 limit.

    # limit coredumpsize unlimited
    # limit
    cputime      unlimited
    filesize     unlimited
    datasize     unlimited
    stacksize    10240 kbytes
    coredumpsize unlimited
    memoryuse    unlimited
    vmemoryuse   unlimited
    descriptors  1024
    memorylocked 32 kbytes
    maxproc      528383
    #
  4. kill -s SEGV <PID>코어 파일이 작성되었는지 확인하려면 cmd를 사용하여 관련 프로세스를 종료 할 수 있습니다 (코어 파일이 작성되지 않은 경우이를 확인으로 사용할 수 있음).

    # kill -s SEGV <PID>

코어 파일이 작성되면 관련 파일 (1./2./3.)에서 코어 덤프 설정을 다시 비활성화하십시오.


9

우분투 14.04

  1. 코어 덤프 활성화 확인 :

    ulimit -a
  2. 라인 중 하나는 다음과 같아야합니다.

    core file size          (blocks, -c) unlimited
  3. 그렇지 않은 경우 :

    gedit ~/.bashrculimit -c unlimited파일 끝에 추가 하고 저장하고 터미널을 다시 실행하십시오.

  4. 디버그 정보로 애플리케이션을 빌드하십시오.

    Makefile에서 -O0 -g

  5. 코어 덤프를 작성하는 애플리케이션을 실행하십시오 (이름이 'core'인 코어 덤프 파일은 application_name 파일 근처에 작성되어야 함).

    ./application_name
  6. gdb에서 실행하십시오.

    gdb application_name core

3 단계에서 터미널을 '재실행'하는 방법은 무엇입니까? 재부팅을 의미합니까?
Naveen

@Naveen no, 터미널을 닫고 새 것을 열면 ulimit -c unlimited터미널 솔루션을 수정 ~/.bashrc해야 변경 사항이 적용 되므로 임시 솔루션을 위해 터미널에 넣을 수도 있습니다 .
mrgloom 2016 년

4

기본적으로 코어 파일이 제공됩니다. 프로세스의 현재 디렉토리가 쓰기 가능하거나 코어 파일이 작성되지 않았는지 확인하십시오.


4
"프로세스의 현재 디렉토리"는 프로세스가 실행될 때 $ cwd를 의미합니까? ~ / abc> / usr / bin / cat def cat이 충돌하면 현재 디렉토리가 ~ / abc 또는 / usr / bin입니까?
Nathan Fellman

5
~ / abc. 흠, 댓글의 길이는 15 자 여야합니다!
Mark Harrison

5
이것은 SEGV 시점의 현재 디렉토리입니다. 또한 실제 사용자 / 그룹과 다른 유효 사용자 및 / 또는 그룹으로 실행되는 프로세스는 코어 파일을 쓰지 않습니다.
Darron

2

system call을 사용하여 프로그래밍 방식으로 코어 덤프를 설정하는 것이 setrlimit좋습니다.

예:

#include <sys/resource.h>

bool enable_core_dump(){    
    struct rlimit corelim;

    corelim.rlim_cur = RLIM_INFINITY;
    corelim.rlim_max = RLIM_INFINITY;

    return (0 == setrlimit(RLIMIT_CORE, &corelim));
}

왜 더 나은가요?
Nathan Fellman

충돌 후 생성 된 코어 파일 ulimit -c unlimited은 명령 행 환경에서 필요하지 않은 다음 응용 프로그램을 다시 실행하십시오.
kgbook

사용자가 개발자에게 연락하여 볼 때만 충돌 할 때마다 코어 덤프를 원하지 않습니다. 100 번 충돌하면 100 개의 코어 덤프가 필요하지 않습니다.
Nathan Fellman

그 경우에는 사용하는 것이 좋습니다 ulimit -c unlimited. 또한 마르코 정의로 컴파일 할 수 있으며, enable_core_dump릴리스시 매크로를 정의 하지 않으면 응용 프로그램에 기호가 포함 되지 않으며 디버그 버전으로 코어 덤프 대체가 제공됩니다.
kgbook

매크로에 의해 자격이 되더라도 다시 실행하기 전에 단순히 쉘에서 명령을 실행하는 대신 코어 덤프를 생성하려면 다시 컴파일해야합니다.
Nathan Fellman

1

당신이있는 경우에 있다는 언급이의 가치 systemd 세트를, 다음 일들이 조금 다릅니다. 설정은 일반적으로 core_patternsysctl 값을 통해 코어 파일이 파이프되도록 합니다 systemd-coredump(8). 코어 파일 크기 rlimit는 일반적으로 이미 "무제한"으로 구성되어 있습니다.

그런 다음을 사용하여 코어 덤프를 검색 할 수 있습니다 coredumpctl(1).

코어 덤프 등의 스토리지는로 구성됩니다 coredump.conf(5). coredumpctl 매뉴얼 페이지에서 코어 파일을 얻는 방법에 대한 예가 있지만 간단히 말하면 다음과 같습니다.

핵심 파일을 찾으십시오.

[vps@phoenix]~$ coredumpctl list test_me | tail -1
Sun 2019-01-20 11:17:33 CET   16163  1224  1224  11 present /home/vps/test_me

핵심 파일을 얻으십시오 :

[vps@phoenix]~$ coredumpctl -o test_me.core dump 16163

0

우분투 19.04

다른 모든 답변 자체는 저에게 도움이되지 않았습니다. 그러나 다음 요약은 일을했습니다.

~/.config/apport/settings다음 내용으로 작성하십시오 .

[main]
unpackaged=true

(이것은 apport가 커스텀 앱을위한 핵심 덤프를 작성하도록 지시합니다)

확인 : ulimit -c. 0을 출력하면

ulimit -c unlimited

경우에 대비하여 apport를 다시 시작하십시오.

sudo systemctl restart apport

충돌 파일이 작성되었습니다 /var/crash/. 그러나 gdb와 함께 사용할 수 없습니다 . gdb와 함께 사용하려면

apport-unpack <location_of_report> <target_directory>

추가 정보 :

  • 일부 답변은 변경을 제안 core_pattern합니다. 다시 시작할 때 apport 서비스가 해당 파일을 덮어 쓸 수 있습니다.
  • 단순히 apport를 중지하면 작업이 수행되지 않았습니다.
  • ulimit -c당신이 웹의 다른 답변을 시도하는 동안 값이 자동으로 변경 얻을 수 있습니다. 코어 덤프 작성을 설정하는 동안 정기적으로 확인하십시오.

참고 문헌 :

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.