From 55a79fbe96a87183fa4e11049eb161943636b1dd Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 22 Sep 2007 10:59:03 +0000 Subject: [PATCH] Use dladdr instead of backtrace_symbols in Backtrace::create (both are GNU-specific anyway) Fix an error handling bug in demangle Output backtrace for uncaught exceptions if one exists --- Build | 6 ++++++ source/core/application.cpp | 16 ++++++++++++++++ source/debug/backtrace.cpp | 25 ++++++++++++++++++++----- source/debug/backtrace.h | 3 ++- source/debug/demangle.cpp | 9 ++++++++- 5 files changed, 52 insertions(+), 7 deletions(-) diff --git a/Build b/Build index 03dc8d2..d7dfac8 100644 --- a/Build +++ b/Build @@ -1,3 +1,5 @@ +/* $Id$ */ + package "mspcore" { version "0.1"; @@ -7,6 +9,10 @@ package "mspcore" if "arch!=win32" { require "pthread"; + build_info + { + library "dl"; + }; }; feature "exception_backtrace" "Generate a backtrace when an exception is thrown."; diff --git a/source/core/application.cpp b/source/core/application.cpp index a498023..3a663db 100644 --- a/source/core/application.cpp +++ b/source/core/application.cpp @@ -6,6 +6,7 @@ Distributed under the LGPL */ #include #include +#include "../debug/backtrace.h" #include "../debug/demangle.h" #include "../time/units.h" #include "../time/utils.h" @@ -60,6 +61,21 @@ int Application::run(int argc, char **argv) cerr<<"An uncaught exception occurred.\n"; cerr<<" type: "<(&e); + if(exc && !exc->get_backtrace().get_frames().empty()) + { + cerr<<" backtrace:\n"; + const Debug::Backtrace::FrameSeq &frames=exc->get_backtrace().get_frames(); + for(Debug::Backtrace::FrameSeq::const_iterator i=frames.begin(); i!=frames.end(); ++i) + { + cerr<<" "<address; + if(!i->symbol.empty()) + cerr<<" in "<symbol; + cerr<<" from "<file<<'\n'; + } + } + delete app_; return 124; } diff --git a/source/debug/backtrace.cpp b/source/debug/backtrace.cpp index c0bfd9d..643fdf2 100644 --- a/source/debug/backtrace.cpp +++ b/source/debug/backtrace.cpp @@ -5,9 +5,11 @@ Copyright © 2007 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ #ifndef WIN32 +#include #include #endif #include "backtrace.h" +#include "demangle.h" using namespace std; @@ -20,13 +22,26 @@ Backtrace Backtrace::create() void *addresses[50]; int count=::backtrace(addresses, 50); - char **symbols=backtrace_symbols(addresses, count); + //char **symbols=backtrace_symbols(addresses, count); Backtrace bt; + Dl_info dli; for(int i=0; iaddress<<" in "<symbol<<'\n'; + out<address<<" in "<symbol<<" from "<file<<'\n'; return out; } diff --git a/source/debug/backtrace.h b/source/debug/backtrace.h index c570ce5..9715df0 100644 --- a/source/debug/backtrace.h +++ b/source/debug/backtrace.h @@ -20,9 +20,10 @@ public: struct StackFrame { void *address; + std::string file; std::string symbol; - StackFrame(void *a, const std::string &s): address(a), symbol(s) { } + //StackFrame(void *a, const std::string &s): address(a), symbol(s) { } }; typedef std::list FrameSeq; diff --git a/source/debug/demangle.cpp b/source/debug/demangle.cpp index 460410e..9ed6e95 100644 --- a/source/debug/demangle.cpp +++ b/source/debug/demangle.cpp @@ -18,8 +18,15 @@ string demangle(const string &sym) #ifdef __GNUC__ int status; char *dm=abi::__cxa_demangle(sym.c_str(), 0, 0, &status); - string result(dm); + + string result; + if(status==0) + result=dm; + else + result=sym; + free(dm); + return result; #else return sym; -- 2.43.0