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) {
#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;
}

View File

@ -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

View File

@ -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 ---");
}
}