분할 오류에서 Linux에서 코어 덤프를 생성하는 방법은 무엇입니까?
Linux에 세그멘테이션 오류가 발생하는 프로세스가 있습니다.오류가 발생했을 때 코어 덤프를 생성하도록 하려면 어떻게 해야 합니까?
사용하는 셸에 따라 다릅니다.bash를 사용하는 경우 ulimit 명령은 코어 덤프 여부와 같은 프로그램 실행과 관련된 몇 가지 설정을 제어합니다.입력하는 경우
ulimit -c unlimited
그러면 프로그램이 모든 크기의 코어를 덤프할 수 있다는 것을 알려줄 것입니다.원하는 경우 무제한 대신 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
by 다시간는sysctl -p
.
코어 파일이 생성되지 않은 경우 다음 방법으로 테스트합니다.sleep 10 &
그리고.killall -SIGSEGV sleep
), 다음을 통해 한계를 확인합니다.ulimit -a
.
코어 파일 크기가 제한된 경우 다음을 실행합니다.
ulimit -c unlimited
무제한으로 만들기 위해.
그런 다음 다시 테스트합니다. 코어 덤프가 성공적이면 아래와 같이 분할 결함 표시 뒤에 "(코어 덤프)"가 표시됩니다.
분할 결함: 11(코어 덤프)
참고 항목: core dumped - 그러나 core 파일이 현재 디렉터리에 없습니까?
우분투
Ubuntu에서 코어 덤프는 Apport에서 처리되며 다음 위치에 위치할 수 있습니다./var/crash/
그러나 안정적인 릴리스에서는 기본적으로 사용할 수 없습니다.
자세한 내용은 다음을 참조하십시오.Ubuntu에서 코어 덤프를 어디서 찾을 수 있습니까?
macOS
macOS의 경우: macOS X에서 코어 덤프를 생성하는 방법을 참조하십시오.
마지막에 제가 한 일은 충돌하기 전에 프로세스에 gdb를 부착한 것이었고, 그리고 나서 세그먼트 결함이 발생했을 때 저는 실행했습니다.generate-core-file
덤프를 했습니다.그 때문에 코어 덤프가 생성되었습니다.
식으로 할, 이은 분할 디버거에 . (은 이런할있다니습이수고디트하랩다버니에입거코방셸대데하니입다원드모래웃된사용아것은서아에래법에한는이식으로할류를로프램은도그분오)이▁used▁(▁code▁maybe▁is▁original▁under▁(▁andthis▁program,▁to▁thisation▁way▁do▁a▁it▁debugger▁a▁out▁trap▁tostration▁of▁how▁the▁this▁you▁could▁fault▁demon코니다▁a▁shells▁segment▁is입드원래이은것런된사용아AIX
및결함 합니다. 및 스택 추적을 분할 결함 지점까지 인쇄합니다.▁the다합니▁를 변경해야 합니다.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 페이지에 설명된 세대를 방해할 수 있는 상황이 더 많습니다. - 시도man core
.
Ubuntu 14.04의 경우
코어 덤프 사용 여부 확인:
ulimit -a
행 중 하나는 다음과 같아야 합니다.
core file size (blocks, -c) unlimited
그렇지 않은 경우:
gedit ~/.bashrc
가추를 합니다.ulimit -c unlimited
파일을 종료하고 저장한 후 터미널을 다시 실행합니다.디버그 정보를 사용하여 응용 프로그램을 만듭니다.
Makefile에서
-O0 -g
코어 덤프를 만드는 응용 프로그램을 실행합니다(이름이 'core'인 코어 덤프 파일은 applicationn_name 파일 근처에 만들어야 합니다).
./application_name
gdb에서 실행:
gdb application_name core
코어 덤프를 활성화하려면 다음을 수행합니다.
/etc/profile
라인에 주석을 달습니다.# ulimit -S -c 0 > /dev/null 2>&1
/etc/security/limits.conf
다음과 같이 설명합니다.* soft core 0
합니다.
limit coredumpsize unlimited
cmdcmd로 합니다.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 #
하려면 cmd 코 파 를 기 록 는 여 cmd 종 있 수 니 습 다 할 료 를 스 프 세 로 어 관 련 사 하 일 용 이 위 되 지 확 해 인 기 하 ▁cmd ▁process▁▁the▁to▁kill니로 관련 프로세스를 종료할 수 .
kill -s SEGV <PID>
이 작성되지 않을 를 대비하여 할 수 있습니다이 파일은 파일을 작성할 필요가 없습니다.)# kill -s SEGV <PID>
코어 파일이 작성되면 관련 파일(1./2./3)에서 코어 덤프 설정을 다시 비활성화해야 합니다!
우분투 19.04
다른 모든 대답 자체는 저에게 도움이 되지 않았습니다.하지만 다음 합계는 일을 했습니다.
를 작성~/.config/apport/settings
다음 내용을 포함합니다.
[main]
unpackaged=true
(이것은 포트가 사용자 지정 앱의 코어 덤프도 작성하도록 지시합니다.)
확인:ulimit -c
출력이 0이면 다음과 같이 고정합니다.
ulimit -c unlimited
앱을 다시 시작할 경우를 대비하여:
sudo systemctl restart apport
충돌파이기다다니록됩음에로 됩니다./var/crash/
그러나 gdb와 함께 사용할 수 없습니다.gdb와 함께 사용하려면 다음을 사용합니다.
apport-unpack <location_of_report> <target_directory>
추가 정보:
- 일부 답변은 변경을 제안합니다.
core_pattern
다시 시작할 때 해당 파일이 apport 서비스에 의해 덮어쓸 수 있습니다. - 단순히 포트를 중지하는 것만으로는 작업이 수행되지 않았습니다.
- 그
ulimit -c
웹의 다른 답변을 시도하는 동안 값이 자동으로 변경될 수 있습니다.코어 덤프 생성을 설정하는 동안 정기적으로 확인해야 합니다.
참조:
기본적으로 코어 파일을 가져옵니다.프로세스의 현재 디렉터리에 쓰기 가능한지 또는 코어 파일이 생성되지 않는지 확인합니다.
시스템 호출을 사용하여 코어 덤프를 프로그래밍 방식으로 설정하는 것이 좋습니다.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));
}
시스템이 설치되어 있다면 상황이 조금 다르다는 것을 언급할 가치가 있습니다.일반적으로 설정은 다음과 같은 방법으로 코어 파일을 파이프로 연결합니다.core_pattern
값,을 통해 통, 과systemd-coredump(8)
일반적으로 코어 파일 크기 제한은 이미 "제한 없음"으로 구성되어 있습니다.
그런 다음 다다을사코여하있수검다습니덤색어프를 사용하여 할 수 .coredumpctl(1)
.
덤프은 덤코프등저다같구이다니성됩음으로 구성됩니다.coredump.conf(5)
coredumpctl man 페이지에서 코어 파일을 가져오는 방법의 예는 다음과 같습니다.
코어 파일 찾기:
[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
일반적으로 충분합니다.
ulimit -c unlimited
SSH 섹션 간에는 이 작업이 유지되지 않습니다!지속성 추가하기
echo '* soft core unlimited' >> /etc/security/limits.conf
이제 Ubuntu를 사용하고 있다면 "apport"가 실행되고 있을 것입니다.확인 방법은 다음과 같습니다.
sudo systemctl status apport.service
그렇다면 다음 장소 중 하나에서 코어 덤프를 발견할 수 있습니다.
/var/lib/apport/coredump
/var/crash
코어 덤프의 위치를 변경하려는 경우
파일을 만들 수 있는 권한이 있고 디렉터리가 코어 덤프를 보낼 디렉터리에 있는지 확인하십시오!
여기 예가 있어요.이는 재부팅 후에도 유지되지 않습니다.
sysctl -w kernel.core_pattern=/coredumps/core-%e-%s-%u-%g-%p-%t
mkdir /coredumps
충돌 중인 프로세스가 이에 대한 쓰기 권한을 가지고 있는지 확인합니다.가장 쉬운 방법은 다음과 같은 예입니다.
chmod 777 /coredumps
코어 덤프가 작동하는지 테스트
> crash.c
gcc -Wl,--defsym=main=0 crash.c
./a.out
==output== Segmentation fault (core dumped)
위에 "core dumped"라고 표시되지 않으면 뭔가 작동하지 않습니다.
언급URL : https://stackoverflow.com/questions/17965/how-to-generate-a-core-dump-in-linux-on-a-segmentation-fault
'it-source' 카테고리의 다른 글
VB에 있는 경우 한 줄.그물 (0) | 2023.05.16 |
---|---|
Azure의 서비스 주체와 관리 ID 간의 차이 (0) | 2023.05.16 |
ViewModel의 명령에 WPF 바인딩 UI 이벤트 (0) | 2023.05.16 |
문자열에서 스트림을 생성하려면 어떻게 해야 합니까? (0) | 2023.05.16 |
옵션 경로에 CORS 헤더를 추가하면 브라우저에서 내 API에 액세스할 수 없는 이유는 무엇입니까? (0) | 2023.05.16 |