| 120 | } |
| 121 | |
| 122 | OutputProxy outputStack(StackCapture stack) { |
| 123 | return OutputProxy([stack = std::move(stack)](std::ostream & os) { |
| 124 | HANDLE process = GetCurrentProcess(); |
| 125 | g_dbgHelpLock.lock(); |
| 126 | for (size_t i = 0; i < stack.second; ++i) { |
| 127 | char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)]; |
| 128 | PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer; |
| 129 | symbol->SizeOfStruct = sizeof(SYMBOL_INFO); |
| 130 | symbol->MaxNameLen = MAX_SYM_NAME; |
| 131 | |
| 132 | format(os, "[{:0{}}] {}", i, (int)log10(stack.second) + 1, (void*)stack.first[i]); |
| 133 | IMAGEHLP_LINE64 line{}; |
| 134 | DWORD displacement = 0; |
| 135 | line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); |
| 136 | if (SymGetLineFromAddr64(process, stack.first[i], &displacement, &line) && *line.FileName) { |
| 137 | char* file = line.FileName; |
| 138 | for (char* i = file; *i; ++i) { |
| 139 | if (*i == '\\' || *i == '/') |
| 140 | file = i; |
| 141 | } |
| 142 | format(os, " ({}:{})", ++file, line.LineNumber); |
| 143 | } |
| 144 | if (SymFromAddr(process, stack.first[i], NULL, symbol)) |
| 145 | format(os, " {}", symbol->Name); |
| 146 | |
| 147 | if (i + 1 < stack.second) |
| 148 | os << std::endl; |
| 149 | } |
| 150 | |
| 151 | if (stack.second == StackLimit) |
| 152 | os << std::endl << "[Stack Output Limit Reached]"; |
| 153 | |
| 154 | g_dbgHelpLock.unlock(); |
| 155 | }); |
| 156 | } |
| 157 | |
| 158 | StarException::StarException() noexcept : StarException(std::string("StarException")) {} |
| 159 |
no test coverage detected