+/* $Id$ */
+
package "mspcore"
{
version "0.1";
if "arch!=win32"
{
require "pthread";
+ build_info
+ {
+ library "dl";
+ };
};
feature "exception_backtrace" "Generate a backtrace when an exception is thrown.";
*/
#include <signal.h>
#include <iostream>
+#include "../debug/backtrace.h"
#include "../debug/demangle.h"
#include "../time/units.h"
#include "../time/utils.h"
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;
}
Distributed under the LGPL
*/
#ifndef WIN32
+#include <dlfcn.h>
#include <execinfo.h>
#endif
#include "backtrace.h"
+#include "demangle.h"
using namespace std;
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
{
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;
}
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;
#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;