C++ app을 stack trace 하려면 어떻게 해야 되나요?
조회수 5583회
제가 c++ app을 만들었는데 이게 자꾸 혼자서 죽어요.
stacktrace
해서 어떻게 되고 있는 건지 보고 싶은데
말만 들었지 방법을 모르겠네요
제 app은 linux
/window
/mac
쓰고 있고
전부 gcc
로 컴파일했습니다.
app이 죽은 다음 유저가 app을 켰을 때
유저한테 물어보고 stack trace
를 받아오고 싶은데요
정보를 받아오는 건 짤 수 있는데 어떤 식으로 trace정보를 저장해야 할지 모르겠습니다. 도와주세요
1 답변
-
linux
/OSX
에서glibc
,gcc
컴파일러를 쓰고 있는 경우에는execinfo.h
헤더의backtrace()
함수를 쓸 수 있습니다.backtrace()
는segmentation fault
가 발생했을 때stacktrace
출력해주고exit
합니다.관련 된 문서는 libc manual을 참고해주세요
SIGSEGV 핸들러를 설정하고, segfault 발생 시 stacktrace를 stderr에 출력해 주는 코드를 첨부하겠습니다. *baz() 함수에서 segfault가 발생하고 handler를 불러옵니다
#include <stdio.h> #include <execinfo.h> #include <signal.h> #include <stdlib.h> #include <unistd.h> void handler(int sig) { void *array[10]; size_t size; // 스택에 있는 모든 void* entry를 가져옴 size = backtrace(array, 10); // stderr에 모든 프레임을 출력 fprintf(stderr, "Error: signal %d:\n", sig); backtrace_symbols_fd(array, size, STDERR_FILENO); exit(1); } void baz() { int *foo = (int*)-1; // 일부러 이상한 포인터를 만들고 printf("%d\n", *foo); // segfault를 발생 } void bar() { baz(); } void foo() { bar(); } int main(int argc, char **argv) { signal(SIGSEGV, handler); // 시그널 핸들러 설정 foo(); // segfault 발생! }
gcc
옵션-g -rdynamic
는stacktrace
에symbol
을 출력해 줍니다. 좀 더 보기 편해져요$ gcc -g -rdynamic ./test.c -o test
로 컴파일했을 때 결과는 다음과 같습니다`$ ./test Error: signal 11: ./test(handler+0x19)[0x400911] /lib64/tls/libc.so.6[0x3a9b92e380] ./test(baz+0x14)[0x400962] ./test(bar+0xe)[0x400983] ./test(foo+0xe)[0x400993] ./test(main+0x28)[0x4009bd] /lib64/tls/libc.so.6(__libc_start_main+0xdb)[0x3a9b91c4bb] ./test[0x40086a]
모듈, offset, 함수를 확인할 수 있고 스택 top에 signal handler가, 그 밑으로 가면서 다른 함수들이 뜨는 게 보이시나요?
댓글 입력