Skip to content

Instantly share code, notes, and snippets.

@skyscribe
Created November 27, 2012 14:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skyscribe/4154534 to your computer and use it in GitHub Desktop.
Save skyscribe/4154534 to your computer and use it in GitHub Desktop.
test backtrace API on Linux/glibc
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()
#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);
}
#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