-/* $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;
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
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;
}