00001 #include "Utilities/General/interface/BackTrace.h" 00002 #include "Utilities/General/interface/ClassName.h" 00003 #include <iostream> 00004 00005 BackTrace::BackTrace() {} 00006 00007 void BackTrace::trace() const { 00008 trace(std::cout); 00009 } 00010 00011 00012 #ifdef __linux__ 00013 00014 #include <execinfo.h> 00015 #include <cstdlib> 00016 #include <cstdio> 00017 #ifndef __USE_GNU 00018 #define __USE_GNU 00019 #endif 00020 00021 #include <dlfcn.h> 00022 #include <cxxabi.h> 00023 00024 void BackTrace::trace(std::ostream & out) const{ 00025 static const int bsize(1024); 00026 char buffer [bsize]; 00027 void * ltrace [MAX_BACKTRACE_DEPTH]; 00028 int depth = backtrace (ltrace, MAX_BACKTRACE_DEPTH); 00029 if (depth>MAX_BACKTRACE_DEPTH) { 00030 out << "Error in backtrace" << std::endl; 00031 return; 00032 } 00033 for (int n = 0; n < depth; ++n) { 00034 unsigned long addr = (unsigned long) ltrace[n]; 00035 Dl_info info; 00036 00037 if (dladdr (ltrace[n], &info) && info.dli_fname && info.dli_fname[0]) { 00038 const char *libname = info.dli_fname; 00039 unsigned long symaddr = (unsigned long) info.dli_saddr; 00040 if (info.dli_sname && info.dli_sname[0]) { 00041 Demangle ln(info.dli_sname); 00042 bool gte = (addr >= symaddr); 00043 unsigned long diff = (gte ? addr - symaddr : symaddr - addr); 00044 sprintf (buffer, " 0x%08lx %.100s %s 0x%lx [%.100s]\n", 00045 addr, ln(), gte ? "+" : "-", diff, libname); 00046 } else 00047 sprintf (buffer, " 0x%08lx <unknown function> [%.100s]\n", addr, libname); 00048 } else { 00049 sprintf (buffer, " 0x%08lx <unknown function>\n", addr); 00050 } 00051 if (::strlen (buffer) > bsize) { 00052 out << "Error in backtrace" << std::endl; 00053 return; 00054 } 00055 out.write (buffer, ::strlen (buffer)); 00056 out.flush(); 00057 } 00058 #ifndef CMS_CHAR_STREAM 00059 out << std::ends; 00060 #endif 00061 } 00062 #else 00063 void BackTrace::trace(ostream & out) const {} 00064 #endif 00065