Lots of cleanups to get stacks properly working in all cases.
This commit is contained in:
		| @@ -20,6 +20,11 @@ namespace ArbUt { | ||||
|         explicit Exception(const std::string& msg) : std::logic_error(msg) { | ||||
| #if !WINDOWS | ||||
|             _stack.load_here(32); | ||||
| #if DEBUG | ||||
|             _stack.skip_n_firsts(2); | ||||
| #else | ||||
|             _stack.skip_n_firsts(0); | ||||
| #endif | ||||
| #endif | ||||
|         } | ||||
|  | ||||
| @@ -67,30 +72,24 @@ namespace ArbUt { | ||||
|             tr.load_stacktrace(stack); | ||||
|             std::stringstream ss; | ||||
|             ss << "Stacktrace with depth " << depth << ": " << std::endl; | ||||
|             bool foundExceptionClass = false; | ||||
|             size_t framesAppended = 0; | ||||
|             for (size_t i = 0; i < stack.size() && framesAppended <= depth; ++i) { | ||||
|             for (size_t i = 0; i < stack.size() && framesAppended < depth; ++i) { | ||||
|                 backward::ResolvedTrace trace = tr.resolve(stack[i]); | ||||
|                 if (trace.source.filename.empty()) { | ||||
|                     AppendNoSourceStack(ss, trace, include_addr); | ||||
|                     if (foundExceptionClass) { | ||||
|                         framesAppended++; | ||||
|                     } | ||||
|                 } else { | ||||
|                     AppendSourceStack(ss, trace.source, foundExceptionClass, snippetFactory); | ||||
|                     if (foundExceptionClass) { | ||||
|                         framesAppended++; | ||||
|                     } | ||||
|                     framesAppended++; | ||||
|                 } else if (i != 0) { | ||||
|                     AppendSourceStack(ss, trace.source, snippetFactory); | ||||
|                     framesAppended++; | ||||
|                 } | ||||
|                 for (auto& t : trace.inliners) { | ||||
|                     AppendSourceStack(ss, t, foundExceptionClass, snippetFactory); | ||||
|                     if (foundExceptionClass) { | ||||
|                         framesAppended++; | ||||
|                         if (framesAppended >= depth) | ||||
|                             break; | ||||
|                     } | ||||
|                     AppendSourceStack(ss, t, snippetFactory); | ||||
|                     framesAppended++; | ||||
|                     if (framesAppended >= depth) | ||||
|                         break; | ||||
|                 } | ||||
|             } | ||||
|             ss << "--- End of Stack ---"; | ||||
|             return ss.str(); | ||||
|         } | ||||
|  | ||||
| @@ -101,9 +100,11 @@ namespace ArbUt { | ||||
|                 (strrchr(trace.object_filename.c_str(), '/') ? strrchr(trace.object_filename.c_str(), '/') + 1 | ||||
|                                                              : trace.object_filename.c_str()); | ||||
|             auto function = trace.object_function; | ||||
|             if (function.length() > 70) { | ||||
|                 function = function.substr(0, 67); | ||||
|                 function += "..."; | ||||
|             if (function.length() == 0) { | ||||
|                 function = "[No function name]"; | ||||
|             } | ||||
|             if (strcmp(objectName, "") == 0) { | ||||
|                 objectName = "[No object name]"; | ||||
|             } | ||||
|             ss << objectName; | ||||
|             if (include_addr) { | ||||
| @@ -112,27 +113,23 @@ namespace ArbUt { | ||||
|             ss << " " << function << std::endl; | ||||
|         } | ||||
|         static void AppendSourceStack(std::stringstream& ss, const backward::ResolvedTrace::SourceLoc& source, | ||||
|                                       bool& foundExceptionClass, backward::SnippetFactory& snippetFactory) { | ||||
|                                       backward::SnippetFactory& snippetFactory) { | ||||
|             auto fileName = (strrchr(source.filename.c_str(), '/') ? strrchr(source.filename.c_str(), '/') + 1 | ||||
|                                                                    : source.filename.c_str()); | ||||
|             if (strcmp(fileName, "Exception.hpp") == 0) { | ||||
|                 foundExceptionClass = true; | ||||
|                 return; | ||||
|             } else if (!foundExceptionClass) { | ||||
|  | ||||
|             auto snippetSearch = snippetFactory.get_snippet(source.filename, source.line, 1); | ||||
|             if (snippetSearch.empty()) { | ||||
|                 ss << fileName << "[" << source.line << "]" << std::endl; | ||||
|                 return; | ||||
|             } | ||||
|             auto snippet = snippetSearch[0].second; | ||||
|  | ||||
|             auto snippet = snippetFactory.get_snippet(source.filename, source.line, 1)[0].second; | ||||
|             size_t p = snippet.find_first_not_of(" \t"); | ||||
|             snippet.erase(0, p); | ||||
|  | ||||
|             p = snippet.find_last_not_of(" \t"); | ||||
|             if (std::string::npos != p) | ||||
|                 snippet.erase(p + 1); | ||||
|             if (snippet.length() > 70) { | ||||
|                 snippet = snippet.substr(0, 67); | ||||
|                 snippet += "..."; | ||||
|             } | ||||
|  | ||||
|             ss << fileName << "[" << source.line << "] " << snippet << std::endl; | ||||
|         } | ||||
|   | ||||
| @@ -82,7 +82,7 @@ namespace ArbUt { | ||||
|  | ||||
|         bool loaded() const { return _loaded; } | ||||
|  | ||||
|         static void handleSignal(int, siginfo_t* info, void* _ctx) { | ||||
|         static void handleSignal(int signal, siginfo_t* info, void* _ctx) { | ||||
|             ucontext_t* uctx = static_cast<ucontext_t*>(_ctx); | ||||
|  | ||||
|             backward::StackTrace st; | ||||
| @@ -115,8 +115,15 @@ namespace ArbUt { | ||||
|             } | ||||
|  | ||||
|             if (_callback != nullptr) { | ||||
|                 auto str = Exception::BuildStacktraceFromStack(st); | ||||
|                 _callback(str.c_str()); | ||||
|                 std::stringstream ss; | ||||
|                 ss << "Encountered signal: " << std::to_string(signal); | ||||
|                 if (signal == 11) { | ||||
|                     if (info->si_code == SEGV_MAPERR) { | ||||
|                         ss << ". Address not mapped: [" << std::hex << info->si_addr << "]"; | ||||
|                     } | ||||
|                 } | ||||
|                 ss << ". With stacktrace:\n" + Exception::BuildStacktraceFromStack(st, 32); | ||||
|                 _callback(ss.str().c_str()); | ||||
|             } | ||||
|  | ||||
| #if _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L | ||||
|   | ||||
| @@ -11,7 +11,8 @@ TEST_CASE("Throw exception get stack trace") { | ||||
|     } catch (const ArbUt::Exception& e) { | ||||
|         REQUIRE(e.GetStacktrace(1) == | ||||
|                 "Stacktrace with depth 1: \n" | ||||
|                 "ExceptionTests.cpp[6] static void Thrower() { throw ArbUt::Exception(\"foobar\"); }\n"); | ||||
|                 "ExceptionTests.cpp[6] static void Thrower() { throw ArbUt::Exception(\"foobar\"); }\n" | ||||
|                 "--- End of Stack ---"); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user