sptk



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Exception stack traces



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

Authoright © Total Knowledge: 2005