Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "ros/debug.h"
00029
00030 #if defined(HAVE_EXECINFO_H)
00031 #include <execinfo.h>
00032 #endif
00033
00034 #if defined(HAVE_CXXABI_H)
00035 #include <cxxabi.h>
00036 #endif
00037
00038 #include <cstdlib>
00039 #include <cstdio>
00040 #include <sstream>
00041
00042 namespace ros
00043 {
00044 namespace debug
00045 {
00046
00047 void getBacktrace(V_void& addresses)
00048 {
00049 #if HAVE_GLIBC_BACKTRACE
00050 void *array[64];
00051
00052 size_t size = backtrace(array, 64);
00053 for (size_t i = 1; i < size; i++)
00054 {
00055 addresses.push_back(array[i]);
00056 }
00057 #endif
00058 }
00059
00060 void translateAddresses(const V_void& addresses, V_string& lines)
00061 {
00062 #if HAVE_GLIBC_BACKTRACE
00063 if (addresses.empty())
00064 {
00065 return;
00066 }
00067
00068 size_t size = addresses.size();
00069 char **strings = backtrace_symbols(&addresses.front(), size);
00070
00071 for (size_t i = 0; i < size; ++i)
00072 {
00073 lines.push_back(strings[i]);
00074 }
00075
00076 free(strings);
00077 #endif
00078 }
00079
00080 std::string demangleName(const std::string& name)
00081 {
00082 #if HAVE_CXXABI_H
00083 int status;
00084 char* demangled = abi::__cxa_demangle(name.c_str(), 0, 0, &status);
00085 std::string out;
00086 if (demangled)
00087 {
00088 out = demangled;
00089 free(demangled);
00090 }
00091 else
00092 {
00093 out = name;
00094 }
00095
00096 return out;
00097 #else
00098 return name;
00099 #endif
00100 }
00101
00102 std::string demangleBacktraceLine(const std::string& line)
00103 {
00104
00105
00106
00107 size_t paren_pos = line.find('(');
00108 size_t plus_pos = line.find('+');
00109 if (paren_pos == std::string::npos || plus_pos == std::string::npos)
00110 {
00111 return line;
00112 }
00113
00114 std::string name(line, paren_pos + 1, plus_pos - paren_pos - 1);
00115 return line.substr(0, paren_pos + 1) + demangleName(name) + line.substr(plus_pos);
00116 }
00117
00118 void demangleBacktrace(const V_string& lines, V_string& demangled)
00119 {
00120 V_string::const_iterator it = lines.begin();
00121 V_string::const_iterator end = lines.end();
00122 for (; it != end; ++it)
00123 {
00124 demangled.push_back(demangleBacktraceLine(*it));
00125 }
00126 }
00127
00128 std::string backtraceToString(const V_void& addresses)
00129 {
00130 V_string lines, demangled;
00131 translateAddresses(addresses, lines);
00132 demangleBacktrace(lines, demangled);
00133
00134 std::stringstream ss;
00135 V_string::const_iterator it = demangled.begin();
00136 V_string::const_iterator end = demangled.end();
00137 for (; it != end; ++it)
00138 {
00139 ss << *it << std::endl;
00140 }
00141
00142 return ss.str();
00143 }
00144
00145 std::string getBacktrace()
00146 {
00147 V_void addresses;
00148 getBacktrace(addresses);
00149 return backtraceToString(addresses);
00150 }
00151
00152 }
00153
00154 }