-
디버깅, call stack back tracec++ 2013. 7. 3. 21:37728x90반응형
누가 이 함수를 호출하였을까?
개발환경 : C++/STL/Linux/gcc
디버깅을 하다보면, 대체 어디서 이 함수를 호출했을까 궁금해질때가 있다. 이럴때 호출한 함수들을 역순으로 알아낼 수 있는 함수 루틴.
#include <execinfo.h>
void call_stack_dump() {
void * array[50];
char ** messages;
int size, i;
size = backtrace(array, 50);
messages = backtrace_symbols(array, size);
// skip first stack frame (points here)
for (i = 0; i < size; ++i){
fprintf(stderr, "[bt]: (%d) %s\n", i, messages[i]);
}
free(messages);
}
컴파일 할때에 -g -rdynamic 옵션을 주어야 한다. 이 방법 말고도 프로그램을 바로 죽여도 좋다면 더 쉬운 방법이 있다.
abort()를 이용하여 코어덤프하고 종료시키자
#include <stdlib.h>
void abort(void);이렇게 하면 core 파일이 생기는데, gdb를 이용하여 back trace하면 자세히 확인할 수 있다.
core 파일을 이용하여 GDB로 Backtrace 하기
$ gdb chat4 core.2838
Core was generated by `/work/chat4 -D'.
Program terminated with signal 6, Aborted.
#0 0xffffe410 in __kernel_vsyscall ()
(gdb) bt
#0 0xffffe410 in __kernel_vsyscall ()
#1 0x00943df0 in raise () from /lib/libc.so.6
#2 0x00945701 in abort () from /lib/libc.so.6
#3 0x080579ed in SigAlarm (signo=14) at chat4.cc:3799
#4 <signal handler called>
#5 0x00982bbb in _int_free () from /lib/libc.so.6
#6 0x00983329 in free () from /lib/libc.so.6
#7 0xf7f50fe1 in operator delete(void*) () from /usr/lib/libstdc++.so.6
#8 0xf7f2dbad in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_M_destroy(std::allocator<char> const&) () from /usr/lib/libstdc++.so.6
#9 0xf7f30757 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() () from /usr/lib/libstdc++.so.6
#10 0x08065515 in __gnu_cxx::new_allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::destroy (this=0xfff3c417, __p=0x9e23750)
...
불특정한 순간에 무한루프에 빠지는 증상을 찾기 위해, SIGALRM을 설정하여, 알람이 발생한 경우 abort()를 호출하여 core dump 하도록 하였다. 이 경우는 string 을 free 하다가 미궁(?)에 빠진 것인데... 아직 정확한 원인은 못 찾고 있다. ㅠㅠ
'c++' 카테고리의 다른 글
The language server crashed. Restarting... (0) 2024.02.21 string을 sprintf, printf 형식으로 사용하기 (0) 2013.07.04 알람 시그널을 이용하여 의도하지 않은 무한루프 디버깅 (0) 2013.07.03