C / C ++에서 프로그래밍 방식으로 코어 덤프를 발생시키는 방법


93

내 C ++ 응용 프로그램의 특정 위치에서 코어 덤프를 강제하고 싶습니다.

나는 다음과 같은 일을함으로써 그것을 할 수 있다는 것을 안다.

int * crash = NULL;
*crash = 1;

하지만 더 깨끗한 방법이 있는지 알고 싶습니다.

그런데 Linux를 사용하고 있습니다.


18
코어 덤프에 대한 "더 깨끗한"방법? .... 좋은 사람;)
OJ.

5
이것은 귀엽다. (? 열거에서 C) 더 나은 아직 부울를 사용 (경우 {/ 충돌이 TRUE =) OH SHI ... * /}
원숭이 - inago

3
BTW,이 방법은 모든 UNIX에서 작동하지 않습니다. HPUX를 사용하면 무단으로 NULL을 읽고 쓸 수 있습니다 (고맙게도 구성 가능).
paxdiablo 2009-06-11

1
저는 3 ~ 4 개의 새로운 것을 배웠습니다. 감사.
Trevor Boyd Smith

@pax 그게 더 일반적인 방법을 찾는 이유입니다;) 감사합니다
hhafez

답변:


76

신호 번호 6을 올리는 것은 ( SIGABRT리눅스에서)이를 수행하는 한 가지 방법입니다 (SIGABRT가 모든 POSIX 구현에서 6 일 필요 는 없으므로 SIGABRT이것이 quick'n이 아닌 경우 값 자체 를 사용하는 것이 좋습니다. '더러운 디버그 코드).

#include <signal.h>
: : :
raise (SIGABRT);

호출 abort()하면 코어 덤프가 발생하며 프로세스 종료 하지 않고도 자식에서 fork()뒤에 오는 것을 호출하여 프로세스 종료 할 수 있습니다 . 자세한 내용 abort()이 답변 을 참조하십시오.


7
SIGABRT는 신호 번호 6이 아니어도됩니다 (종종, 특히 Linux에서 그렇습니다).
Jonathan Leffler

4
아니요, 맞습니다. 그렇지는 않지만 디버그 코드의 정확성에 대해 너무 걱정하지 않는 경향이 있습니다. 야생으로 그 탈출, 내 코드의 청결 내 걱정 :-)의 이상입니다
paxdiablo

2
abort () 함수가 noreturn 속성으로 선언되고 컴파일러가 모든 반환 정보를 완전히 최적화 하므로 일부 컴파일러와 일부 C 라이브러리 (예 : ARM의 gcc 및 glibc 또는 uClibc)가있는 일부 아키텍처에서는 abort () 호출이 쓸모가 없습니다. 코어 파일을 사용할 수 없게됩니다. raise () 또는 abort () 자체 호출 이후에는 추적 할 수 없습니다. 따라서 raise (SIGABRT)를 직접 호출하거나 사실상 동일한 kill (getpid (), SIGABRT)를 호출하는 것이 훨씬 좋습니다.
Alexander Amelkin 2014

3
죄송합니다. ARM에서는 raise (SIGABRT)에서도 같은 일이 발생합니다. 따라서 추적 가능한 코어 파일을 생성하는 유일한 방법은 kill (getpid (), SIGABRT)
Alexander Amelkin 2014

ulimit -c unlimitedSuvesh Pratapa 답변 의 힌트 는이 답변에 많은 도움이되었습니다.
Boris Däppen

74

몇 년 전 Google은 coredumper 라이브러리를 출시했습니다 .

개요

coredumper 라이브러리를 응용 프로그램으로 컴파일하여 종료하지 않고 실행중인 프로그램의 코어 덤프를 만들 수 있습니다. 커널이 기본적으로 다중 스레드 코어 파일을 지원하지 않더라도 단일 및 다중 스레드 코어 덤프를 모두 지원합니다.

Coredumper는 BSD 라이선스 조건에 따라 배포됩니다.

이것은 결코 완전한 예가 아닙니다. coredumper API가 어떻게 생겼는지에 대한 느낌을 줄뿐입니다.

#include <google/coredumper.h>
...
WriteCoreDump('core.myprogram');
/* Keep going, we generated a core file,
 * but we didn't crash.
 */

당신이 요구 한 것은 아니지만 아마도 더 좋을 것입니다 :)


3
이 답변을 보았을 때 처음에는 꽤 흥분했습니다. 그러나 코어 덤퍼는 요즘 꽤 낡고 낡아 보입니다. 그것은 현대 리눅스에 더 이상 작동하지 않는 경우에도 표시가 커널의 : stackoverflow.com/questions/38314020/...
jefe2000

37

에 나열된으로 신호 맨 '핵심'으로 표시된 조치에 어떤 신호가 코어 덤프를 강제 할 것이다. 몇 가지 예는 다음과 같습니다.

SIGQUIT       3       Core    Quit from keyboard
SIGILL        4       Core    Illegal Instruction
SIGABRT       6       Core    Abort signal from abort(3)
SIGFPE        8       Core    Floating point exception
SIGSEGV      11       Core    Invalid memory reference

코어 덤프를 활성화했는지 확인하십시오.

ulimit -c unlimited

감사합니다 ulimit -c unlimited. 도움을 받아 코어 덤프를 활성화하는 것에 대한 귀하의 의견 입니다.

코드 내에서 ulimit를 어떻게 설정합니까? @ ks1322
카란 Joisher

@KaranJoisher 아마도 그 자체로 또 다른 질문의 가치가 있지만 간단히 말해서을 setrlimit(RLIMIT_CORE, &core_limits);통해 사용할 수 있습니다 #include <sys/resource.h>. 유형의 구조체를 rlimit만든 다음 rlim_currlim_max멤버 를 설정합니다 .
Brent,



6

코어 덤프를 생성하는 또 다른 방법 :

$ bash
$ kill -s SIGSEGV $$

bash의 새 인스턴스를 만들고 지정된 신호로 종료하면됩니다. 는 $$쉘의 PID입니다. 그렇지 않으면 현재 bash를 죽이고 로그 아웃되고 터미널이 닫히거나 연결이 끊어집니다.

$ bash 
$ kill -s SIGABRT $$
$ bash
$ kill -s SIGFPE $$

매우 간단하고 유용합니다!
firo

1
저도 좋아합니다. 로 단순화 할 수도 있습니다 bash -c 'kill -SIGSEGV $$'.
Christian Krause 2014 년

4

kill (2) 를 사용하여 신호를 보낼 수 있습니다 .

#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);

그래서,

kill(getpid(), SIGSEGV);

예. 답변에 추가했습니다.
Eugene Yokota

2

때때로 다음과 같이하는 것이 적절할 수 있습니다.

int st = 0;
pid_t p = fork();

if (!p) {
    signal(SIGABRT, SIG_DFL);
    abort(); // having the coredump of the exact copy of the calling thread
} else {
    waitpid(p, &st, 0); // rip the zombie
}

// here the original process continues to live

이 간단한 접근 방식의 한 가지 문제점은 하나의 스레드 만 코어 덤프된다는 것입니다.


1
 #include <stdio.h>
 #include <stdlib.h>
 int main()
 {
   printf("\n");
   printf("Process is aborting\n");
   abort();
   printf("Control not reaching here\n");
   return 0;
 }

원하는 곳 에서이 접근 방식을 사용하십시오. :)


0
#include <assert.h>
.
.
.
     assert(!"this should not happen");

아마도 NDEBUG를 처리해야하므로이 특정 주장은 다른 주장이 아닌 경우에도 활성화됩니다.
의 Rhys Ulerich
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.