Lots of cleanups to get stacks properly working in all cases.
This commit is contained in:
parent
0e49c58647
commit
95266f71ba
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 ---");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue