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

Linux에서 세그먼테이션 오류가 발생하는 프로세스가 있습니다. 실패시 코어 덤프를 생성하도록하려면 어떻게해야합니까?



답변

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

ulimit -c unlimited

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

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

limit coredumpsize unlimited


답변

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

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

gcore <pid>

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

kill -ABRT <pid>

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


답변

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

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에서 코어 덤프를 생성하는 방법은 무엇입니까?


답변

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


답변

어쩌면 이런 식으로 할 수 있습니다.이 프로그램은 세그먼테이션 오류를 포착하고 디버거 (이것은 아래에서 사용되는 원래 코드 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가 코어를 덤프하도록 매개 변수를 추가해야 할 수도 있습니다 .


답변

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

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

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


답변

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

  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.)에서 코어 덤프 설정을 다시 비활성화하십시오.