00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #include "Backtrace.hh"
00027
00028
00029
00030 #include <senf/config.hh>
00031 #ifdef SENF_BACKTRACE
00032 #include <execinfo.h>
00033 #include <errno.h>
00034 #endif
00035 #include <cxxabi.h>
00036 #include <boost/regex.hpp>
00037 #include "Buffer.hh"
00038
00039
00040 #define prefix_
00041
00042
00043 prefix_ void senf::formatBacktrace(std::ostream & os, void ** backtrace, int numEntries)
00044 {
00045 #ifdef SENF_BACKTRACE
00046 char ** symbols (::backtrace_symbols(backtrace, numEntries));
00047 if (symbols == NULL) {
00048 os << "error on translating backtrace addresses with ::backtrace_symbols: " << std::strerror(errno);
00049 return;
00050 }
00051
00052 static boost::regex const backtraceRx
00053 ("(.*)\\((.*)\\+(0x[0-9a-f]+)\\) \\[(0x[0-9a-f]+)\\]");
00054 enum { File = 1,
00055 Symbol = 2,
00056 Offset = 3,
00057 Address = 4 };
00058
00059 for (int i=0; i<numEntries; ++i) {
00060 std::string sym (symbols[i]);
00061 boost::smatch match;
00062 if (regex_match(sym, match, backtraceRx)) {
00063 std::string symbol (match[Symbol]);
00064 int status (0);
00065 char * demangled ( abi::__cxa_demangle(symbol.c_str(), 0, 0, &status) );
00066 if (demangled) {
00067 symbol = std::string(demangled);
00068 free(demangled);
00069 }
00070 os << " " << symbol << " + " << match[Offset]
00071 << "\n in " << match[File] << " [" << match[Address] << "]\n";
00072 }
00073 else if (sym == "[0xffffe410]")
00074 os << " __kernel_vsyscall [0xffffe410]\n";
00075 else if (sym == "[0xffffe420]")
00076 os << " __kernel_sigreturn [0xffffe410]\n";
00077 else if (sym == "[0xffffe440]")
00078 os << " __kernel_rt_sigreturn [0xffffe440]\n";
00079 else
00080 os << " " << sym << "\n";
00081 }
00082 free(symbols);
00083 #endif
00084 #ifndef SENF_DEBUG
00085 os << "no backtrace available please compile SENF without final=1\n";
00086 #endif
00087
00088 }
00089
00090 prefix_ void senf::backtrace(std::ostream & os, int numEntries)
00091 {
00092 #ifdef SENF_BACKTRACE
00093 SENF_SCOPED_BUFFER( void*, entries, numEntries);
00094 int n ( ::backtrace(entries, numEntries) );
00095 senf::formatBacktrace(os, entries, n);
00096 #endif
00097 }
00098
00099
00100 #undef prefix_
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112