//--There is list of options:
//a) backtrace in combination with abi::__cxa_demangle
//b) GDB
//c) [libunwind][1], [http://www.nongnu.org/libunwind/docs.html]
//d) libbfd-dev
//e) [backward-cpp][1], [https://github.com/bombela/backward-cpp]
//f) [libbacktrace][1], [https://github.com/ErwanLegrand/libbacktrace]
//-----------------------------------------------
#include <execinfo.h>
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <sstream>
#include <sys/wait.h>
//-----------------------------------------------
//Based on GDB
//-----------------------------------------------
void print_trace_gdb() {
char pid_buf[30];
sprintf(pid_buf, "%d", getpid());
char name_buf[512];
name_buf[readlink("/proc/self/exe", name_buf, 511)]=0;
int child_pid = fork();
if (!child_pid) {
dup2(2,1); // redirect output to stderr
fprintf(stdout,"stack trace for %s pid=%s\n",name_buf, pid_buf);
execlp("gdb", "gdb", "--batch", "-n", "-ex", "thread", "-ex", "bt", name_buf, pid_buf, NULL);
//if gdb failed to start
abort();
} else {
waitpid(child_pid,NULL,0);
}
}
//-----------------------------------------------
void rec_function(int ii)
{
if (ii == 0) {std::cout << "int value==" << ii << "\n";}
else {rec_function(--ii);}
print_trace_gdb();
}
//-----------------------------------------------
int main()
{
int jj=1;
std::cout << "\n---begin test-----\n";
std::cout << "int value==" << jj << "\n";
rec_function(jj);
std::cout << "---end test-----\n";
}
출력
---begin test-----
int value==1
int value==0
stack trace for /opt/cpp/linux_backtrace_gdb pid=4181
0x00007f878b5ca4ca in waitpid() from /lib/x86_64-linux-gnu/libc.so.6
[Current thread is 1 (process 4181)]
#0 0x00007f878b5ca4ca in waitpid() from /lib/x86_64-linux-gnu/libc.so.6
#1 0x0000000000400e69 in print_trace_gdb() at linux_backtrace_gdb.cpp:25
#2 0x0000000000400ed2 in rec_function (ii=0) at linux_backtrace_gdb.cpp:34
#3 0x0000000000400ecd in rec_function (ii=0) at linux_backtrace_gdb.cpp:33
#4 0x0000000000400f29 in main() at linux_backtrace_gdb.cpp:43
stack trace for /opt/cpp/linux_backtrace_gdb pid=4181
0x00007f878b5ca4ca in waitpid() from /lib/x86_64-linux-gnu/libc.so.6
[Current thread is 1 (process 4181)]
#0 0x00007f878b5ca4ca in waitpid() from /lib/x86_64-linux-gnu/libc.so.6
#1 0x0000000000400e69 in print_trace_gdb() at linux_backtrace_gdb.cpp:25
#2 0x0000000000400ed2 in rec_function (ii=0) at linux_backtrace_gdb.cpp:34
#3 0x0000000000400f29 in main() at linux_backtrace_gdb.cpp:43
---end test-----
컴파일 라인이다 [g ++ --std = C++ 11 -g linux_backtrace_gdb.cpp -o linux_backtrace_gdb -rdynamic] –
오, 이런, 안돼! 'backtrace() '의 핵심은 프로세스 내에서 실행된다는 것입니다. 'gdb'로 셸링하는 것은 훨씬 더 나쁜 방법입니다. GDB가 심볼을 초기화하고로드하는 동안 전체 프로세스가 중지 될 수 있습니다. (물론 GDB를 설치해야합니다.) – duskwuff
backtrace()를 사용하면 [abi :: __ cxa_demangle] 및/또는 lib2addr를 사용하는 경우에도 문제가 발생한 행 번호를 찾을 수 있습니다. GDB는 소프트웨어의 비 릴리스/디버그 버전에서 사용하기에 꽤 괜찮습니다. –