CPPSERV


Home Projects Jobs Clientele Contact
CPPSERV Documentation Download TODO Mailing lists Bug tracker News RSS Feed Browse source

Tracleable.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2004-2006 by Ilya A. Volynets-Evenbakh                  *
00003  *   ilya@total-knowledge.com                                              *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
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     // Start with 1, in order to exclude this constructor itself
00040     // from the trace. We know we've been here anyways :)
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                     //s.insert(p,"cannot demangle: mangled name is invalid under C++ ABI rules.");
00069                     //do nothing, since this is the case of C names...
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         // Do nothing... We can't handle this problem
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 }

SourceForge.net Logo