CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/Utilities/General/src/BackTrace.cc

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