Use dladdr instead of backtrace_symbols in Backtrace::create (both are GNU-specific...
authorMikko Rasa <tdb@tdb.fi>
Sat, 22 Sep 2007 10:59:03 +0000 (10:59 +0000)
committerMikko Rasa <tdb@tdb.fi>
Sat, 22 Sep 2007 10:59:03 +0000 (10:59 +0000)
Fix an error handling bug in demangle
Output backtrace for uncaught exceptions if one exists

Build
source/core/application.cpp
source/debug/backtrace.cpp
source/debug/backtrace.h
source/debug/demangle.cpp

diff --git a/Build b/Build
index 03dc8d22c3625eef39df51cc42ba98003c4203c9..d7dfac8dfb1ad5c98b4af54c5bf00937de80adaa 100644 (file)
--- 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.";
index a49802350f2f7d655125d8ab0480d9e41370c72a..3a663dbb63b77fa85b4cf8ac9546d7543d6d7f98 100644 (file)
@@ -6,6 +6,7 @@ Distributed under the LGPL
 */
 #include <signal.h>
 #include <iostream>
+#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:   "<<Debug::demangle(typeid(e).name())<<'\n';
                cerr<<"  what(): "<<e.what()<<'\n';
+
+               const Exception *exc=dynamic_cast<const Exception *>(&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<<"    "<<i->address;
+                               if(!i->symbol.empty())
+                                       cerr<<" in "<<i->symbol;
+                               cerr<<" from "<<i->file<<'\n';
+                       }
+               }
+
                delete app_;
                return 124;
        }
index c0bfd9d9ca16158e898b7ecd2625eb9375d3bc6d..643fdf2bb03288dd16cdd3605e473d675541a479 100644 (file)
@@ -5,9 +5,11 @@ Copyright © 2007 Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 #ifndef WIN32
+#include <dlfcn.h>
 #include <execinfo.h>
 #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; i<count; ++i)
-               bt.frames.push_back(StackFrame(addresses[i], symbols[i]));
-
-       free(symbols);
+       {
+               StackFrame frame;
+               frame.address=addresses[i];
+               if(dladdr(addresses[i], &dli))
+               {
+                       frame.file=dli.dli_fname;
+                       if(dli.dli_sname)
+                               frame.symbol=demangle(dli.dli_sname);
+               }
+               else
+                       frame.file="<unknown>";
+               bt.frames.push_back(frame);
+       }
+
+       //free(symbols);
 
        return bt;
 #else
@@ -38,7 +53,7 @@ ostream &operator<<(ostream &out, const Backtrace &bt)
 {
        const Backtrace::FrameSeq &frames=bt.get_frames();
        for(Backtrace::FrameSeq::const_iterator i=frames.begin(); i!=frames.end(); ++i)
-               out<<i->address<<" in "<<i->symbol<<'\n';
+               out<<i->address<<" in "<<i->symbol<<" from "<<i->file<<'\n';
 
        return out;
 }
index c570ce5d0746f0dd31106132f052ae8d2c715426..9715df0ed8026c395af1cf1b865b1fc9b4ba4a64 100644 (file)
@@ -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<StackFrame> FrameSeq;
 
index 460410e49569f501ed4792929650c62068cdf243..9ed6e95f84f1d9447ef19d6b31ad1d0fc6b8304f 100644 (file)
@@ -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;