Lots of cleanups to get stacks properly working in all cases.

This commit is contained in:
Deukhoofd 2020-12-23 12:04:20 +01:00
parent 0e49c58647
commit 95266f71ba
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
3 changed files with 38 additions and 33 deletions

View File

@ -20,6 +20,11 @@ namespace ArbUt {
explicit Exception(const std::string& msg) : std::logic_error(msg) { explicit Exception(const std::string& msg) : std::logic_error(msg) {
#if !WINDOWS #if !WINDOWS
_stack.load_here(32); _stack.load_here(32);
#if DEBUG
_stack.skip_n_firsts(2);
#else
_stack.skip_n_firsts(0);
#endif
#endif #endif
} }
@ -67,30 +72,24 @@ namespace ArbUt {
tr.load_stacktrace(stack); tr.load_stacktrace(stack);
std::stringstream ss; std::stringstream ss;
ss << "Stacktrace with depth " << depth << ": " << std::endl; ss << "Stacktrace with depth " << depth << ": " << std::endl;
bool foundExceptionClass = false;
size_t framesAppended = 0; 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]); backward::ResolvedTrace trace = tr.resolve(stack[i]);
if (trace.source.filename.empty()) { if (trace.source.filename.empty()) {
AppendNoSourceStack(ss, trace, include_addr); AppendNoSourceStack(ss, trace, include_addr);
if (foundExceptionClass) {
framesAppended++; framesAppended++;
} } else if (i != 0) {
} else { AppendSourceStack(ss, trace.source, snippetFactory);
AppendSourceStack(ss, trace.source, foundExceptionClass, snippetFactory);
if (foundExceptionClass) {
framesAppended++; framesAppended++;
} }
}
for (auto& t : trace.inliners) { for (auto& t : trace.inliners) {
AppendSourceStack(ss, t, foundExceptionClass, snippetFactory); AppendSourceStack(ss, t, snippetFactory);
if (foundExceptionClass) {
framesAppended++; framesAppended++;
if (framesAppended >= depth) if (framesAppended >= depth)
break; break;
} }
} }
} ss << "--- End of Stack ---";
return ss.str(); return ss.str();
} }
@ -101,9 +100,11 @@ namespace ArbUt {
(strrchr(trace.object_filename.c_str(), '/') ? strrchr(trace.object_filename.c_str(), '/') + 1 (strrchr(trace.object_filename.c_str(), '/') ? strrchr(trace.object_filename.c_str(), '/') + 1
: trace.object_filename.c_str()); : trace.object_filename.c_str());
auto function = trace.object_function; auto function = trace.object_function;
if (function.length() > 70) { if (function.length() == 0) {
function = function.substr(0, 67); function = "[No function name]";
function += "..."; }
if (strcmp(objectName, "") == 0) {
objectName = "[No object name]";
} }
ss << objectName; ss << objectName;
if (include_addr) { if (include_addr) {
@ -112,27 +113,23 @@ namespace ArbUt {
ss << " " << function << std::endl; ss << " " << function << std::endl;
} }
static void AppendSourceStack(std::stringstream& ss, const backward::ResolvedTrace::SourceLoc& source, 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 auto fileName = (strrchr(source.filename.c_str(), '/') ? strrchr(source.filename.c_str(), '/') + 1
: source.filename.c_str()); : source.filename.c_str());
if (strcmp(fileName, "Exception.hpp") == 0) {
foundExceptionClass = true; auto snippetSearch = snippetFactory.get_snippet(source.filename, source.line, 1);
return; if (snippetSearch.empty()) {
} else if (!foundExceptionClass) { ss << fileName << "[" << source.line << "]" << std::endl;
return; 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"); size_t p = snippet.find_first_not_of(" \t");
snippet.erase(0, p); snippet.erase(0, p);
p = snippet.find_last_not_of(" \t"); p = snippet.find_last_not_of(" \t");
if (std::string::npos != p) if (std::string::npos != p)
snippet.erase(p + 1); snippet.erase(p + 1);
if (snippet.length() > 70) {
snippet = snippet.substr(0, 67);
snippet += "...";
}
ss << fileName << "[" << source.line << "] " << snippet << std::endl; ss << fileName << "[" << source.line << "] " << snippet << std::endl;
} }

View File

@ -82,7 +82,7 @@ namespace ArbUt {
bool loaded() const { return _loaded; } 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); ucontext_t* uctx = static_cast<ucontext_t*>(_ctx);
backward::StackTrace st; backward::StackTrace st;
@ -115,8 +115,15 @@ namespace ArbUt {
} }
if (_callback != nullptr) { if (_callback != nullptr) {
auto str = Exception::BuildStacktraceFromStack(st); std::stringstream ss;
_callback(str.c_str()); 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 #if _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L

View File

@ -11,7 +11,8 @@ TEST_CASE("Throw exception get stack trace") {
} catch (const ArbUt::Exception& e) { } catch (const ArbUt::Exception& e) {
REQUIRE(e.GetStacktrace(1) == REQUIRE(e.GetStacktrace(1) ==
"Stacktrace with depth 1: \n" "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 ---");
} }
} }