Tracleable.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <servlet/Traceable.h>
00021 #include <execinfo.h>
00022 #include <iostream>
00023 #include <cxxabi.h>
00024 #include <stdlib.h>
00025
00026 namespace servlet {
00027
00028 #define MAX_TRACE 40
00029
00033 Traceable::Traceable(const std::string& msg)
00034 : msg(msg)
00035 {
00036 void * array[MAX_TRACE];
00037 int nSize = backtrace(array, MAX_TRACE);
00038 char ** symbols = backtrace_symbols(array, nSize);
00039
00040
00041 trace.resize(nSize-1);
00042 char* dmBuf=(char*)malloc(120);
00043 char* dmName;
00044 size_t sz=120;
00045 try {
00046 for(int i=1;i<nSize;i++){
00047 std::string &s(trace[nSize-1-i]);
00048 s.assign(symbols[i]);
00049 std::string::size_type p=s.find('('),p2=std::string::npos;
00050 if(p!=std::string::npos){
00051 p2=s.find(')',++p);
00052 }
00053 int st=-1;
00054 if(p!=std::string::npos && p2!=std::string::npos) {
00055 std::string::size_type plus=s.find('+', p);
00056 p2--;
00057 if(plus==std::string::npos)
00058 plus=p2;
00059 std::string s2=(s.substr(p,plus-p));
00060 dmName=abi::__cxa_demangle(s2.c_str(),dmBuf,&sz,&st);
00061 }
00062 if(st!=0) {
00063 switch(st) {
00064 case -3:
00065 s.insert(p,"cannot demangle: one of the arguments is invalid.");
00066 break;
00067 case -2:
00068
00069
00070 break;
00071 case -1:
00072 s.insert(p,"cannot demangle: memory allocation failure");
00073 break;
00074 default:
00075 s.insert(p,"unknown error while demangling ");
00076 }
00077 }else if(dmName){
00078 s.erase(p,p2-p+1);
00079 s.insert(p,dmName);
00080 dmBuf = dmName;
00081 }
00082 }
00083 } catch (...) {
00084
00085 }
00086 if(dmBuf) free(dmBuf);
00087 if(symbols) ::free(symbols);
00088 }
00089
00093 Traceable::~Traceable() throw()
00094 {
00095 }
00096
00097 }
00098
00099
00105 void servlet::Traceable::printStackTrace(std::ostream& os) const
00106 {
00107 os<<getMsg()<<":\n";
00108 for(trace_t::const_iterator i=trace.begin();i!=trace.end();i++){
00109 os<<*i<<std::endl;
00110 }
00111 }