debug.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009, Willow Garage, Inc.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright notice,
7  * this list of conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright
9  * notice, this list of conditions and the following disclaimer in the
10  * documentation and/or other materials provided with the distribution.
11  * * Neither the names of Stanford University or Willow Garage, Inc. nor the names of its
12  * contributors may be used to endorse or promote products derived from
13  * this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "ros/debug.h"
29 
30 #if defined(HAVE_EXECINFO_H)
31 #include <execinfo.h>
32 #endif
33 
34 #if defined(HAVE_CXXABI_H)
35 #include <cxxabi.h>
36 #endif
37 
38 #include <cstdlib>
39 #include <cstdio>
40 #include <sstream>
41 
42 namespace ros
43 {
44 namespace debug
45 {
46 
47 void getBacktrace(V_void& addresses)
48 {
49 #if HAVE_GLIBC_BACKTRACE
50  void *array[64];
51 
52  size_t size = backtrace(array, 64);
53  for (size_t i = 1; i < size; i++)
54  {
55  addresses.push_back(array[i]);
56  }
57 #endif
58 }
59 
60 void translateAddresses(const V_void& addresses, V_string& lines)
61 {
62 #if HAVE_GLIBC_BACKTRACE
63  if (addresses.empty())
64  {
65  return;
66  }
67 
68  size_t size = addresses.size();
69  char **strings = backtrace_symbols(&addresses.front(), size);
70 
71  for (size_t i = 0; i < size; ++i)
72  {
73  lines.push_back(strings[i]);
74  }
75 
76  free(strings);
77 #endif
78 }
79 
80 std::string demangleName(const std::string& name)
81 {
82 #if HAVE_CXXABI_H
83  int status;
84  char* demangled = abi::__cxa_demangle(name.c_str(), 0, 0, &status);
85  std::string out;
86  if (demangled)
87  {
88  out = demangled;
89  free(demangled);
90  }
91  else
92  {
93  out = name;
94  }
95 
96  return out;
97 #else
98  return name;
99 #endif
100 }
101 
102 std::string demangleBacktraceLine(const std::string& line)
103 {
104  // backtrace_symbols outputs in the form:
105  // executable(function+offset) [address]
106  // We want everything between ( and + to send to demangleName()
107  size_t paren_pos = line.find('(');
108  size_t plus_pos = line.find('+');
109  if (paren_pos == std::string::npos || plus_pos == std::string::npos)
110  {
111  return line;
112  }
113 
114  std::string name(line, paren_pos + 1, plus_pos - paren_pos - 1);
115  return line.substr(0, paren_pos + 1) + demangleName(name) + line.substr(plus_pos);
116 }
117 
118 void demangleBacktrace(const V_string& lines, V_string& demangled)
119 {
120  V_string::const_iterator it = lines.begin();
121  V_string::const_iterator end = lines.end();
122  for (; it != end; ++it)
123  {
124  demangled.push_back(demangleBacktraceLine(*it));
125  }
126 }
127 
128 std::string backtraceToString(const V_void& addresses)
129 {
130  V_string lines, demangled;
131  translateAddresses(addresses, lines);
132  demangleBacktrace(lines, demangled);
133 
134  std::stringstream ss;
135  V_string::const_iterator it = demangled.begin();
136  V_string::const_iterator end = demangled.end();
137  for (; it != end; ++it)
138  {
139  ss << *it << std::endl;
140  }
141 
142  return ss.str();
143 }
144 
145 std::string getBacktrace()
146 {
147  V_void addresses;
148  getBacktrace(addresses);
149  return backtraceToString(addresses);
150 }
151 
152 }
153 
154 }
ros::debug::backtraceToString
CPP_COMMON_DECL std::string backtraceToString(const V_void &addresses)
Definition: debug.cpp:128
ros::debug::demangleBacktrace
CPP_COMMON_DECL void demangleBacktrace(const V_string &names, V_string &demangled)
Definition: debug.cpp:118
ros
Definition: datatypes.h:39
ros::debug::demangleName
CPP_COMMON_DECL std::string demangleName(const std::string &name)
Definition: debug.cpp:80
ros::debug::demangleBacktraceLine
std::string demangleBacktraceLine(const std::string &line)
Definition: debug.cpp:102
ros::debug::V_void
std::vector< void * > V_void
Definition: debug.h:40
ros::debug::getBacktrace
CPP_COMMON_DECL std::string getBacktrace()
Definition: debug.cpp:145
ros::debug::V_string
std::vector< std::string > V_string
Definition: debug.h:41
debug.h
ros::debug::translateAddresses
CPP_COMMON_DECL void translateAddresses(const V_void &addresses, V_string &lines)
Definition: debug.cpp:60


cpp_common
Author(s): John Faust, Dirk Thomas
autogenerated on Sat Jun 17 2023 02:32:37