C++ app을 stack trace 하려면 어떻게 해야 되나요?


제가 c++ app을 만들었는데 이게 자꾸 혼자서 죽어요. stacktrace 해서 어떻게 되고 있는 건지 보고 싶은데 말만 들었지 방법을 모르겠네요

제 app은 linux/window/mac 쓰고 있고 전부 gcc로 컴파일했습니다.

app이 죽은 다음 유저가 app을 켰을 때 유저한테 물어보고 stack trace를 받아오고 싶은데요

정보를 받아오는 건 짤 수 있는데 어떤 식으로 trace정보를 저장해야 할지 모르겠습니다. 도와주세요

  • 2016년 01월 15일에 작성됨

조회수 427


1 답변


좋아요
0
싫어요
채택취소하기

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 -rdynamicstacktracesymbol을 출력해 줍니다. 좀 더 보기 편해져요

$ 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가, 그 밑으로 가면서 다른 함수들이 뜨는 게 보이시나요?

  • 2016년 01월 15일에 작성됨

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close