Skip to content
Snippets Groups Projects
Commit 20a8d15a authored by g0dil's avatar g0dil
Browse files

Utils: Add backtrace to exception message in SENF_DEBUG builds

parent 8a65ae6f
No related branches found
No related tags found
No related merge requests found
......@@ -27,6 +27,10 @@
//#include "Exception.ih"
// Custom includes
#include <execinfo.h>
#include <sstream>
#include "../config.hh"
#include "impl/demangle.h"
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
......@@ -44,6 +48,38 @@ prefix_ char const * senf::Exception::what()
return message_.c_str();
}
#ifdef SENF_DEBUG
prefix_ void senf::Exception::addBacktrace()
{
void * entries[SENF_DEBUG_BACKTRACE_NUMCALLERS];
unsigned nEntries( ::backtrace(entries, SENF_DEBUG_BACKTRACE_NUMCALLERS) );
char ** symbols = ::backtrace_symbols(entries, nEntries);
std::stringstream ss;
ss << "\nException at\n";
for (unsigned i=0; i<nEntries; ++i) {
std::string sym (symbols[i]);
std::string::size_type fnStart (sym.find("("));
if (fnStart != std::string::npos) {
std::string::size_type fnEnd (sym.find(")",fnStart+1));
if (fnEnd != std::string::npos) {
std::string fn (sym,fnStart+1, fnEnd-fnStart-1);
char * demangled ( ::cplus_demangle(fn.c_str(),
DMGL_TYPES|DMGL_AUTO) );
if (demangled) {
ss << " " << demangled << "( ... )" << std::string(sym,fnEnd+1) << "\n";
continue;
}
}
}
ss << " " << sym << "\n";
}
ss << "-- \n" << message_;
message_ = ss.str();
free(symbols);
}
#endif
///////////////////////////////////////////////////////////////////////////
// senf::SystemException
......
......@@ -32,7 +32,11 @@
prefix_ senf::Exception::Exception(std::string const & description)
: message_(description)
{}
{
#ifdef SENF_DEBUG
addBacktrace();
#endif
}
prefix_ std::string const & senf::Exception::message()
const
......
......@@ -79,6 +79,11 @@
struct FooException : public senf::Exception
{ FooException() : senf::Exception("Foo hit the fan") {} };
\endcode
If SENF is compiled in debug mode (SENF_DEBUG is defined), the exception message will
automatically include a stack backtrace. For this to work, you need to add the
<tt>-rdynamic</tt> option to all link commands. This feature depends on <tt>gcc</tt> and
the GNU-libc.
*/
namespace senf {
......@@ -117,6 +122,9 @@ namespace senf {
exceptions. */
private:
#ifdef SENF_DEBUG
void addBacktrace();
#endif
std::string message_;
};
......
......@@ -51,7 +51,11 @@ BOOST_AUTO_UNIT_TEST(errnoException)
catch (senf::SystemException & e) {
BOOST_CHECK_EQUAL( e.errorNumber(), ENOENT );
BOOST_CHECK_EQUAL( e.errorString(), "No such file or directory" );
BOOST_CHECK_EQUAL( e.what(), "[No such file or directory] ::open()\nmore\nx=1\ny=2" );
std::string what (e.what());
std::string::size_type pos (what.find("-- \n"));
if (pos != std::string::npos)
what = std::string(what, pos+4);
BOOST_CHECK_EQUAL( what, "[No such file or directory] ::open()\nmore\nx=1\ny=2" );
}
}
......
......@@ -76,6 +76,10 @@
# define SENF_SENFLOG_LIMIT senf::log::NOTICE
# endif
# endif
#
# ifndef SENF_DEBUG_BACKTRACE_NUMCALLERS
# define SENF_DEBUG_BACKTRACE_NUMCALLERS 64
# endif
#
# ///////////////////////////////hh.e////////////////////////////////////////
# endif
......
......@@ -253,7 +253,7 @@ def MakeEnvironment():
# CPPDEFINES = [ '_GLIBCXX_DEBUG' ],
env.Append(CXXFLAGS = [ '-O0', '-g', '-fno-inline' ],
CPPDEFINES = [ 'SENF_DEBUG' ],
LINKFLAGS = [ '-g' ])
LINKFLAGS = [ '-g', '-rdynamic' ])
env.Append(CPPDEFINES = [ '$EXTRA_DEFINES' ],
LIBS = [ '$EXTRA_LIBS' ],
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment