#include <csignal> #include <iostream> #include <stdlib.h> #include <sstream> namespace SigCatchDebug { void (*original)(int); bool installed = false; std::string file_; int line_ = 0; std::stringstream data; void debug_sig(int type) { if(line_ != 0) { std::cout << "Signal Caught!!!" << std::endl << "last trace loc:" << file_ << ":" << line_ << std::endl << "----- data was ---- " << std::endl << data.str() << std::endl << std::endl; } if(original != SIG_DFL || original != SIG_IGN) (*original)(type); std::exit(EXIT_FAILURE); //<<-- this really needs to be here! } class AutoScope { public: AutoScope(const char* file, const int line) { if(!installed) { installed = true; original = std::signal (SIGSEGV,debug_sig); if (original == SIG_ERR) { std::cout << "signal implosion" << std::endl; } //std::cout << "signal installed" << std::endl; } file_ = file; line_ = line; data.str(""); } template<typename T> inline AutoScope& operator<<(const T& t) throw() { try { data << t; } catch (...) {} return *this; } ~AutoScope() { //std::cout << "signal disable" << std::endl; line_ = 0; } void jump(int line) { line_ = line; } }; } void evil_random_crashing_func() { static count = 0; char** test = NULL; SigCatchDebug::AutoScope sigScope(__FILE__,__LINE__); sigScope << "test: " << test << "\n" << "count: " << count; sigScope.jump(__LINE__); if(count == 3) test[0] = "ABCDEFG"; sigScope.jump(__LINE__); if(count == 4) std::cout << "evil_random_crashing_func: " << test[0] << std::endl; std::cout << "Evil " << count << std::endl; count++; } void evil_random_crashing_func2() { char** test = NULL; test[0] = "ABCDEFG"; std::cout << "evil_random_crashing_func2: " << test[0] << std::endl; } int main(int argc, char const * const *argv) { try { evil_random_crashing_func(); evil_random_crashing_func(); //evil_random_crashing_func2(); evil_random_crashing_func(); evil_random_crashing_func(); } catch (std::exception const &e) { std::cout << "Unexpected exception: " << e.what() << std::endl; } catch (...) { std::cout << "Unexpected exception" << std::endl; } return 0; }
Tuesday, March 1, 2011
Debuging random segvs
This code is a simple and Focused segv catcher, it is designed for transient and random errors, the ones where you never know when or if they are going to happen. The idea is to use a local varable to scope the monitered area and keep tabs of the last line of code with the jump function. There is a streaming mech to gather input params and other data along the way(ie you can log the local vars in it after the fact). Then when a segv actually happens it wakes up and informs you of where it feel over and what the logged data was.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment