]> git.tdb.fi Git - libs/core.git/blobdiff - source/debug/backtrace.cpp
Use #ifdef _WIN32 rather than WIN32
[libs/core.git] / source / debug / backtrace.cpp
index 2078996c41d234bb138f8cb29c4805e7894cd9ab..f9057dce833d95b9231917bd763a489f7a856fb1 100644 (file)
@@ -1,11 +1,11 @@
-/* $Id$
-
-This file is part of libmspcore
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
-Distributed under the LGPL
-*/
+// Must include something to test for glibc
+#include <cstdlib>
+#if !defined(_WIN32) && defined(__GLIBC__)
+#include <dlfcn.h>
 #include <execinfo.h>
+#endif
 #include "backtrace.h"
+#include "demangle.h"
 
 using namespace std;
 
@@ -14,17 +14,26 @@ namespace Debug {
 
 Backtrace Backtrace::create()
 {
-#ifndef WIN32
+#if !defined(_WIN32) && defined(__GLIBC__)
        void *addresses[50];
-       int count=::backtrace(addresses, 50);
-
-       char **symbols=backtrace_symbols(addresses, count);
+       int count = ::backtrace(addresses, 50);
 
        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);
+       }
 
        return bt;
 #else
@@ -34,9 +43,19 @@ Backtrace Backtrace::create()
 
 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';
+       const list<Backtrace::StackFrame> &frames = bt.get_frames();
+       for(list<Backtrace::StackFrame>::const_iterator i=frames.begin(); i!=frames.end(); ++i)
+               out<<*i<<'\n';
+
+       return out;
+}
+
+ostream &operator<<(ostream &out, const Backtrace::StackFrame &sf)
+{
+       out<<sf.address;
+       if(!sf.symbol.empty())
+               out<<" in "<<sf.symbol;
+       out<<" from "<<sf.file;
 
        return out;
 }