Created
November 27, 2012 14:35
-
-
Save skyscribe/4154534 to your computer and use it in GitHub Desktop.
test backtrace API on Linux/glibc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
bld |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cmake_minimum_required(VERSION 2.8) | |
set(CMAKE_C_COMPILER "gcc-4.7") | |
set(CMAKE_CXX_COMPILER "g++-4.7") | |
add_definitions(-std=c++0x -rdynamic) | |
add_executable(test_bt test_bt.cpp) | |
add_executable(test_bt_mt test_bt_mt.cpp) | |
foreach(t test_bt test_bt_mt) | |
target_link_libraries(${t} pthread) | |
endforeach() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <signal.h> | |
#include <execinfo.h> | |
#include <cstdio> | |
#include <cstring> | |
#include <cstdlib> | |
#include <iostream> | |
#include <thread> | |
using namespace std; | |
int faultOp(){ | |
char* addrPtr = reinterpret_cast<char*>(0x1); | |
cout << (*addrPtr) << endl; | |
} | |
int outFunc(int num){ | |
if (num > 2) | |
outFunc(num-1); | |
faultOp(); | |
} | |
void handleCore(int signo){ | |
printf("Signal caught:%d\n", signo); | |
char* stack[20] = {0}; | |
int depth = backtrace(reinterpret_cast<void**>(stack), sizeof(stack)/sizeof(stack[0])); | |
if (depth){ | |
char** symbols = backtrace_symbols(reinterpret_cast<void**>(stack), depth); | |
if (symbols){ | |
for(size_t i = 0; i < depth; i++){ | |
printf("===[%d]:%s\n", (i+1), symbols[i]); | |
} | |
} | |
free(symbols); | |
} | |
//re-throw | |
raise(SIGSEGV); | |
} | |
int main(){ | |
struct sigaction act; | |
memset(&act, 0, sizeof(act)); | |
act.sa_handler = &handleCore; | |
act.sa_flags |= SA_RESETHAND; //one-time only | |
sigaction(SIGSEGV, &act, NULL); | |
outFunc(6); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <signal.h> | |
#include <unistd.h> | |
#include <execinfo.h> | |
#include <cstdio> | |
#include <cstring> | |
#include <cstdlib> | |
#include <iostream> | |
#include <thread> | |
using namespace std; | |
int faultOp(){ | |
char* addrPtr = reinterpret_cast<char*>(0x1); | |
cout << (*addrPtr) << endl; | |
} | |
int outFunc(int num){ | |
if (num > 2) | |
outFunc(num-1); | |
faultOp(); | |
} | |
void handleCore(int signo){ | |
printf("Signal caught:%d, dumping backtrace...\n", signo); | |
char* stack[20] = {0}; | |
int depth = backtrace(reinterpret_cast<void**>(stack), sizeof(stack)/sizeof(stack[0])); | |
if (depth){ | |
char** symbols = backtrace_symbols(reinterpret_cast<void**>(stack), depth); | |
if (symbols){ | |
for(size_t i = 0; i < depth; i++){ | |
printf("===[%d]:%s\n", (i+1), symbols[i]); | |
} | |
} | |
free(symbols); | |
} | |
sleep(3); | |
//re-throw | |
raise(SIGSEGV); | |
} | |
void normalOp(){ | |
cout << "THREAD-" << std::this_thread::get_id() << ": normal operation begin..." << endl; | |
sleep(2); | |
cout << "THREAD-" << std::this_thread::get_id() << ": normal operation end..." << endl; | |
} | |
void threadFunc(size_t id){ | |
if (id == 1){ | |
cout << "THREAD-" << std::this_thread::get_id() << ":bad operation follows..." << endl; | |
outFunc(6); | |
}else{ | |
normalOp(); | |
} | |
} | |
int main(){ | |
struct sigaction act; | |
memset(&act, 0, sizeof(act)); | |
act.sa_handler = &handleCore; | |
act.sa_flags |= SA_RESETHAND; //one-time only | |
sigaction(SIGSEGV, &act, NULL); | |
thread t1(bind(&threadFunc, 1)); | |
thread t2(bind(&threadFunc, 2)); | |
thread t3(bind(&threadFunc, 3)); | |
cout << "Threads started!" << endl; | |
t1.join(); | |
t2.join(); | |
t3.join(); | |
//below prints will never get dumped | |
cout << "All threads exited!" << endl; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment