TDME2  1.9.200
RTTI.cpp
Go to the documentation of this file.
1 #include <tdme/tdme.h>
2 #include <tdme/utilities/RTTI.h>
3 
4 #if defined(_WIN32) && defined(_MSC_VER)
5  // no op
6 #else
7  #include <cxxabi.h>
8  #include <stdlib.h>
9 
10  #if !defined(_WIN32) && !defined(__HAIKU__)
11  #include <stdio.h>
12  #include <execinfo.h>
13  #include <signal.h>
14  #include <unistd.h>
15  #endif
16 #endif
17 
18 #include <string>
19 
20 using std::string;
21 using std::to_string;
22 
24 
25 const string RTTI::demangle(const string& name) {
26  #if defined(_WIN32) && defined(_MSC_VER)
27  auto demangledNameString = name;
28  return demangledNameString;
29  #else
30  int status;
31  char* demangledName = abi::__cxa_demangle(name.c_str(), 0, 0, &status);
32  string demangledNameString(demangledName == nullptr?name:demangledName);
33  free(demangledName);
34  return demangledNameString;
35  #endif
36 }
37 
38 const string RTTI::backtrace() {
39  #if defined(_WIN32) || defined(__HAIKU__)
40  return "No backtrace available";
41  #else
42  // Note: This is *nix only and requires to compile with -rdynamic flag
43  void* buffer[50];
44  auto size = ::backtrace(buffer, 50);
45  auto strings = ::backtrace_symbols(buffer, size);
46  if (strings == nullptr) return "No backtrace available";
47  string result;
48  // https://stackoverflow.com/questions/77005/how-to-automatically-generate-a-stacktrace-when-my-program-crashes
49  for (int i = 1; i < size && strings != nullptr; ++i) {
50  char* mangledName = 0, *offsetBegin = 0, *offsetEnd = 0;
51  // find parantheses and +address offset surrounding mangled name
52  for (char* p = strings[i]; *p; ++p) {
53  if (*p == '(') {
54  mangledName = p;
55  } else if (*p == '+') {
56  offsetBegin = p;
57  } else if (*p == ')') {
58  offsetEnd = p;
59  break;
60  }
61  }
62  // if the line could be processed, attempt to demangle the symbol
63  if (mangledName && offsetBegin && offsetEnd && mangledName < offsetBegin) {
64  *mangledName++ = '\0';
65  *offsetBegin++ = '\0';
66  *offsetEnd++ = '\0';
67  int status;
68  char* realName = abi::__cxa_demangle(mangledName, 0, 0, &status);
69  // if demangling is successful, output the demangled function name
70  if (status == 0) {
71  result+= to_string(i) + ": " + strings[i] + ": " + realName + "\n";
72  } else {
73  // otherwise, output the mangled function name
74  result+= to_string(i) + ": " + strings[i] + ": " + mangledName + "\n";
75  }
76  free(realName);
77  } else {
78  // otherwise, print the whole line
79  result+= to_string(i) + ": " + strings[i] + "\n";
80  }
81  }
82  free(strings);
83  return result;
84  #endif
85 }
Run time type information utility class.
Definition: RTTI.h:14
static const string backtrace()
Returns the current backtrace as string.
Definition: RTTI.cpp:38