Main MRPT website > C++ reference for MRPT 1.5.6
backtrace.cpp
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 
10 #include "base-precomp.h" // Precompiled headers
11 
12 #include <mrpt/system/backtrace.h>
13 
14 #ifdef MRPT_OS_WINDOWS
15  #define WIN32_LEAN_AND_MEAN
16  #include <windows.h>
17  #include <DbgHelp.h>
18 #else
19  #include <execinfo.h>
20  #include <dlfcn.h> // dladdr()
21  #include <cxxabi.h> // __cxa_demangle()
22  #include <cstdlib>
23  #include <string>
24  #include <sstream>
25  #include <iostream>
26 #endif
27 
29 {
30  out_bt.backtrace_levels.clear();
31  const unsigned int framesToSkip = 1; // skip *this* function from the backtrace
32  const unsigned int framesToCapture = 64;
33 
34 #ifdef MRPT_OS_WINDOWS
35  void* backTrace[framesToCapture]{};
36 
37  SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
38  const HANDLE hProcess = GetCurrentProcess();
39  if (!SymInitialize(hProcess, nullptr /* UserSearchPath */, TRUE /*fInvadeProcess*/))
40  {
41  std::cerr << "[mrpt::system::getCallStackBackTrace] Error in SymInitialize()!" << std::endl;
42  return;
43  }
44 
45  char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
46  PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
47  pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
48  pSymbol->MaxNameLen = MAX_SYM_NAME;
49 
50  const USHORT nFrames = CaptureStackBackTrace(framesToSkip, framesToCapture, backTrace, nullptr);
51  for (unsigned int i = 0; i < nFrames; i++)
52  {
53  TCallStackEntry cse;
54  cse.address = backTrace[i];
55 
56  if (!SymFromAddr(hProcess, (DWORD64)cse.address, nullptr, pSymbol))
57  {
58  cse.symbolName = "???";
59  cse.symbolNameOriginal = "???";
60  out_bt.backtrace_levels.emplace_back(cse);
61  continue;
62  }
63  SYMBOL_INFO &si = *pSymbol;
64 
65  cse.symbolNameOriginal = si.Name;
66  char undecorated_name[1024];
67  if (!UnDecorateSymbolName(si.Name, undecorated_name, sizeof(undecorated_name), UNDNAME_COMPLETE))
68  {
70  }
71  else
72  {
73  cse.symbolName = std::string(undecorated_name);
74  }
75 
76  out_bt.backtrace_levels.emplace_back(cse);
77  }
78 #else
79  // Based on: https://gist.github.com/fmela/591333
80  void *callstack[framesToCapture];
81  const int nMaxFrames = sizeof(callstack) / sizeof(callstack[0]);
82  int nFrames = ::backtrace(callstack, nMaxFrames);
83  char **symbols = ::backtrace_symbols(callstack, nFrames);
84 
85  for (int i = (int)framesToSkip; i < nFrames; i++)
86  {
87  TCallStackEntry cse;
88  cse.address = callstack[i];
89 
90  Dl_info info;
91  if (dladdr(callstack[i], &info) && info.dli_sname)
92  {
93  char *demangled = NULL;
94  int status = -1;
95  if (info.dli_sname[0] == '_')
96  {
97  demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status);
98  }
99  cse.symbolNameOriginal = info.dli_sname == 0 ? symbols[i] : info.dli_sname;
100  cse.symbolName = status == 0 ? std::string(demangled) : cse.symbolNameOriginal;
101  free(demangled);
102  }
103  out_bt.backtrace_levels.emplace_back(cse);
104  }
105  free(symbols);
106 #endif
107 }
108 
110 {
111 }
112 
114 {
115  std::ostringstream trace_buf;
116  trace_buf << "Callstack backtrace:" << std::endl;
117  for (unsigned int i = 0; i < this->backtrace_levels.size(); i++)
118  {
119  trace_buf << mrpt::format("[%-2d] %*p %s", i, int(2 + sizeof(void*) * 2), backtrace_levels[i].address, backtrace_levels[i].symbolName.c_str()) << std::endl;
120  }
121  return trace_buf.str();
122 }
Used in getCallStackBackTrace()
Definition: backtrace.h:20
GLuint buffer
Definition: glext.h:3775
void BASE_IMPEXP getCallStackBackTrace(TCallStackBackTrace &out_bt)
Returns a list of strings representing the current call stack backtrace.
Definition: backtrace.cpp:28
void * address
Address of the calling point.
Definition: backtrace.h:24
std::string symbolName
Demangled symbol name.
Definition: backtrace.h:26
std::vector< TCallStackEntry > backtrace_levels
Definition: backtrace.h:39
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
GLsizei const GLchar ** string
Definition: glext.h:3919
#define TRUE
Definition: jmorecfg.h:230
std::string symbolNameOriginal
Original (before demangle) symbol name.
Definition: backtrace.h:28
See: getCallStackBackTrace()
Definition: backtrace.h:36
backing_store_ptr info
Definition: jmemsys.h:170
_u8 status
Definition: rplidar_cmd.h:21
GLuint address
Definition: glext.h:6078
std::string asString() const
Prints all backtrace entries, one per line in a human-readable format.
Definition: backtrace.cpp:113



Page generated by Doxygen 1.8.14 for MRPT 1.5.6 Git: 4c65e8431 Tue Apr 24 08:18:17 2018 +0200 at lun oct 28 01:35:26 CET 2019