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