Whatever. I'll just keep it in CPPSERV, where I originally wrote it. Alexey Parshin wrote:
Simply put, I don't have any urge or time for that, and I beleive that shouldn't be a part of SPTK. If you want you can always have your own class derived from std::exception. Or, if you beleive that you can fit that Windows crap into 50 lines - go ahead. I can't do it, and you can't. Before we have both parts small and clean - this code shouldn't be a part of SPTK. And lets wrap it for now. Alexey 02.10.05, Ilya A. Volynets-Evenbakh<ilya@total-knowledge.com> написал(а):This is because he does structured exceptions as well as C++ exceptions - basically handles things like GPF - which I'm not doing in Unix, so you don't have to do it in winblows either. That should simlify some things. All you have to do is get his stack parsing code, and use it in CException constructor. Alexey Parshin wrote:Не смешно. Ты видел - сколько там кода? Один класс sym_engine - 650 строк. Заключение - к терапевту. 2005/10/2, Ilya A. Volynets-Evenbakh <ilya@total-knowledge.com>:take a look at http://www.codeproject.com/cpp/exception.asp It has instructions on how to write that functionality for VC++. I'd do it myself, if I had anywhere to debug it ;-) Alexey Parshin wrote:First, do you really need this? It's a feature that is only available under g++. It's against of the project idea - any feature is available on all platforms. So, if you want it - find the equvalent solution for Windows, an we put it in. Otherwise - I'm sorry.. 2005/10/2, Ilya A. Volynets-Evenbakh <ilya@total-knowledge.com>:Attached is a patch that allows to print stack trace from exception handlers that catch CException-derived exceptions (did I use word "exception" enough time while describing this exception handler enhancement?) In order to enable it, one has to be using g++ to compile SPTK, and one has to pass --enable-stacktrace option to configure. Otherwise all this functionality becomes noop. The interface is rather simple - stack trace info is collected automagically at the moment exception object is created, and handler can use printStackTrace(std::ostream&) function to output the exception. Now, one thing that is missing, is printing out of the trace in case exception wasn't caugt. I am pretty sure it is doable, but don't see _much_ point in bothering. If one wants that kind of thing, just enclose whole main function in try-catch block. Of course that wouldn't address exception in static object constructor, but such exceptions are bad idea anyways. Another TODO, is obviously writing similar functionality for VC++ (which is possible - I know for sure - I just don't have tools to debug that). OK to put it in? -- Ilya A. Volynets-Evenbakh Total Knowledge. CTO http://www.total-knowledge.com diff --git a/configure.in b/configure.in --- a/configure.in +++ b/configure.in @@ -63,6 +63,7 @@ AC_ARG_ENABLE(excel, [ --enable-exce AC_ARG_ENABLE(odbc, [ --enable-odbc use ODBC if installed (default=yes)]) AC_ARG_ENABLE(fltk, [ --enable-fltk use FLTK if installed (default=yes)]) AC_ARG_ENABLE(examples, [ --enable-examples build examples (default=no)]) +AC_ARG_ENABLE(stacktrace,[ --enable-stacktrace enable stack traces in exception handlers(default=yes)]) if test x$enable_debug = xyes; then DEBUGFLAG="-g3 -O0" @@ -192,6 +193,12 @@ AC_SUBST(POSTBUILD) AC_CHECK_LIB(pthread,pthread_rwlock_timedrdlock,AC_DEFINE(HAVE_PTHREAD_RWLOCK_TIMEDRDLOCK,[1],[Have pthread_rwlock_timedrdlock])) AC_CHECK_LIB(pthread,pthread_rwlock_timedwrlock,AC_DEFINE(HAVE_PTHREAD_RWLOCK_TIMEDWRLOCK,[1],[Have pthread_rwlock_timedwrlock])) +AC_LANG(C++) dnl switch over to C++, since cxxabi.h is C++ file +AC_CHECK_HEADERS(execinfo.h cxxabi.h,[], [enable_stacktrace=no]) +if test x"$enable_stacktrace" = xno; then + AC_DEFINE(SPTK_STACK_TRACE, [1], [Enable stack traces in exceptions]) +fi + dnl Write all of the files... AC_CONFIG_HEADERS(sptk3/sptk-config.h) AC_OUTPUT(Makefile sptk3/Makefile sptk3/excel/Makefile sptk3/xml/Makefile examples/Makefile .themes.sptk/Makefile) @@ -236,6 +243,12 @@ else echo "Debug info: generated ($DEBUGFLAG)" fi +if test x"$enable_stacktrace" = x"no"; then + echo "Stack traces: disabled" +else + echo "Stack traces: enabled" +fi + if test x$enable_examples = xyes; then echo "Examples: built" else diff --git a/sptk3/CException.h b/sptk3/CException.h --- a/sptk3/CException.h +++ b/sptk3/CException.h @@ -39,6 +39,10 @@ class SP_EXPORT CException : public std: std::string m_text; ///< The exception text std::string m_description; ///< The extended error information std::string m_fullMessage; ///< The complete error information combining everything together +#ifdef SPTK_EXCEPTION_TRACE + typedef __gnu_cxx::slist<std::string> trace_t; + trace_t trace; ///< The list of functions on call stack at time of exception creation +#endif /* SPTK_EXCEPTION_TRACE */ public: /// Constructor /// @param text std::string, the exception text @@ -64,6 +68,10 @@ public: /// Returns exception description std::string description() const { return m_description; } + + /// Pritnts functions that where on call stack + /// at the time exception was thrown + void printStackTrace(std::ostream& os); }; #define throwException(msg) throw CException(msg,__FILE__,__LINE__) diff --git a/src/CException.cpp b/src/CException.cpp --- a/src/CException.cpp +++ b/src/CException.cpp @@ -27,6 +27,11 @@ #include <sptk3/CException.h> #include <sptk3/CStrings.h> +#ifdef SPTK_EXCEPTION_TRACE +#include <execinfo.h> +#include <iostream> +#include <cxxabi.h> +#endif /* SPTK_EXCEPTION_TRACE*/ using namespace std; @@ -42,4 +47,41 @@ CException::CException(string text,strin if (!m_description.empty()) m_fullMessage += "\n" + m_description; + +#ifdef SPTK_EXCEPTION_TRACE + { + void * array[MAX_TRACE]; + int nSize = backtrace(array, MAX_TRACE); + char ** symbols = backtrace_symbols(array, nSize); + for(int i=0;i<nSize;i++){ + std::string s(symbols[i]); + std::string::size_type sz=0,p=s.find('('),p2=std::string::npos; + if(p!=std::string::npos){ + p2=s.find('+',++p); + } + char* dmName=0; + int st=-1; + if(p!=std::string::npos && p2!=std::string::npos) { + std::string s2=(s.substr(p,p2-p)); + dmName=abi::__cxa_demangle(s2.c_str(),NULL,&sz,&st); + } + if(dmName&&st==0){ + s.replace(p,p2-p,dmName,sz); + free(dmName); + } + trace.push_front(s); + } + free(symbols); + } +#endif /* SPTK_EXCEPTION_TRACE */ +} + +void CException::printStackTrace(std::ostream& os) +{ +#ifdef SPTK_EXCEPTION_TRACE + os<<getMsg()<<":\n"; + for(trace_t::iterator i=trace.begin();i!=trace.end();i++){ + os<<*i<<std::endl; + } +#endif /* SPTK_EXCEPTION_TRACE */ }-- Alexey Parshin, http://www.sptk.net-- Ilya A. Volynets-Evenbakh Total Knowledge. CTO http://www.total-knowledge.com-- Alexey Parshin, http://www.sptk.net-- Ilya A. Volynets-Evenbakh Total Knowledge. CTO http://www.total-knowledge.com-- Alexey Parshin, http://www.sptk.net
-- Ilya A. Volynets-Evenbakh Total Knowledge. CTO http://www.total-knowledge.com
List hosted by Total Knowledge