| 90 | } |
| 91 | |
| 92 | void StackTracePrintPrivateData::critErrHandler(int sig_num, siginfo_t* info, void* ucontext) |
| 93 | { |
| 94 | // Prevent running a function that isn't supported on certain platforms. |
| 95 | #if not defined (__i386__) & not defined (__x86_64__) |
| 96 | std::cout << "No error handler supported for this platform" << std::endl; |
| 97 | return; |
| 98 | #endif |
| 99 | // We print the callstack in a stringstream. Then, we will print it to the crashStream |
| 100 | // and, then, to the log manager |
| 101 | std::stringstream crashStream; |
| 102 | |
| 103 | void* array[50]; |
| 104 | void* caller_address; |
| 105 | sig_ucontext_t* uc = static_cast<sig_ucontext_t*>(ucontext); |
| 106 | |
| 107 | #if defined(__i386__) // gcc specific |
| 108 | caller_address = reinterpret_cast<void*>(uc->uc_mcontext.eip); // EIP: x86 specific |
| 109 | #elif defined(__x86_64__) // gcc specific |
| 110 | caller_address = reinterpret_cast<void*>(uc->uc_mcontext.rip); // RIP: x86_64 specific |
| 111 | #else |
| 112 | #error Unsupported architecture. // TODO: Add support for other arch. |
| 113 | #endif |
| 114 | // void* caller_address = (void*) uc->uc_mcontext.eip; // x86 specific |
| 115 | |
| 116 | crashStream << "signal " << sig_num |
| 117 | << " (" << strsignal(sig_num) << "), address is " |
| 118 | << info->si_addr << " from " << caller_address |
| 119 | << std::endl << std::endl; |
| 120 | |
| 121 | int size = backtrace(array, 50); |
| 122 | |
| 123 | array[1] = caller_address; |
| 124 | |
| 125 | char** messages = backtrace_symbols(array, size); |
| 126 | |
| 127 | // skip first stack frame (points here) |
| 128 | for (int i = 1; i < size && messages != nullptr; ++i) |
| 129 | { |
| 130 | char* mangled_name = nullptr, *offset_begin = nullptr, *offset_end = nullptr; |
| 131 | |
| 132 | // find parantheses and +address offset surrounding mangled name |
| 133 | for (char* p = messages[i]; *p; ++p) |
| 134 | { |
| 135 | if (*p == '(') |
| 136 | { |
| 137 | mangled_name = p; |
| 138 | } |
| 139 | else if (*p == '+') |
| 140 | { |
| 141 | offset_begin = p; |
| 142 | } |
| 143 | else if (*p == ')') |
| 144 | { |
| 145 | offset_end = p; |
| 146 | break; |
| 147 | } |
| 148 | } |
| 149 |
nothing calls this directly
no test coverage detected