Improve terminate handler behavior when there's no active exception and also try to print a trace for non-cpptrace terminates
This commit is contained in:
parent
f6f64954de
commit
ae484f0ed2
@ -114,7 +114,8 @@ namespace cpptrace {
|
|||||||
inline const_iterator cbegin() const noexcept { return frames.cbegin(); }
|
inline const_iterator cbegin() const noexcept { return frames.cbegin(); }
|
||||||
inline const_iterator cend() const noexcept { return frames.cend(); }
|
inline const_iterator cend() const noexcept { return frames.cend(); }
|
||||||
private:
|
private:
|
||||||
CPPTRACE_API void print(std::ostream& stream, bool color, bool newline_at_end) const;
|
CPPTRACE_API void print(std::ostream& stream, bool color, bool newline_at_end, const char* header) const;
|
||||||
|
friend void print_terminate_trace();
|
||||||
};
|
};
|
||||||
|
|
||||||
CPPTRACE_API raw_trace generate_raw_trace(std::uint_least32_t skip = 0);
|
CPPTRACE_API raw_trace generate_raw_trace(std::uint_least32_t skip = 0);
|
||||||
|
|||||||
@ -160,15 +160,15 @@ namespace cpptrace {
|
|||||||
|
|
||||||
CPPTRACE_API
|
CPPTRACE_API
|
||||||
void stacktrace::print(std::ostream& stream, bool color) const {
|
void stacktrace::print(std::ostream& stream, bool color) const {
|
||||||
print(stream, color, true);
|
print(stream, color, true, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
CPPTRACE_API
|
||||||
void stacktrace::print(std::ostream& stream, bool color, bool newline_at_end) const {
|
void stacktrace::print(std::ostream& stream, bool color, bool newline_at_end, const char* header) const {
|
||||||
if(color) {
|
if(color) {
|
||||||
detail::enable_virtual_terminal_processing_if_needed();
|
detail::enable_virtual_terminal_processing_if_needed();
|
||||||
}
|
}
|
||||||
stream<<"Stack trace (most recent call first):"<<std::endl;
|
stream<<(header ? header : "Stack trace (most recent call first):")<<std::endl;
|
||||||
std::size_t counter = 0;
|
std::size_t counter = 0;
|
||||||
if(frames.empty()) {
|
if(frames.empty()) {
|
||||||
stream<<"<empty trace>"<<std::endl;
|
stream<<"<empty trace>"<<std::endl;
|
||||||
@ -237,7 +237,7 @@ namespace cpptrace {
|
|||||||
CPPTRACE_API
|
CPPTRACE_API
|
||||||
std::string stacktrace::to_string(bool color) const {
|
std::string stacktrace::to_string(bool color) const {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
print(oss, color, false);
|
print(oss, color, false, nullptr);
|
||||||
return std::move(oss).str();
|
return std::move(oss).str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,27 +329,45 @@ namespace cpptrace {
|
|||||||
CPPTRACE_API extern const int stdout_fileno = detail::fileno(stdout);
|
CPPTRACE_API extern const int stdout_fileno = detail::fileno(stdout);
|
||||||
CPPTRACE_API extern const int stderr_fileno = detail::fileno(stderr);
|
CPPTRACE_API extern const int stderr_fileno = detail::fileno(stderr);
|
||||||
|
|
||||||
|
CPPTRACE_FORCE_NO_INLINE void print_terminate_trace() {
|
||||||
|
generate_trace(1).print(
|
||||||
|
std::cerr,
|
||||||
|
isatty(stderr_fileno),
|
||||||
|
true,
|
||||||
|
"Stack trace to reach terminate handler (most recent call first):"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
[[noreturn]] CPPTRACE_API void terminate_handler() {
|
[[noreturn]] CPPTRACE_API void terminate_handler() {
|
||||||
try {
|
try {
|
||||||
std::rethrow_exception(std::current_exception());
|
auto ptr = std::current_exception();
|
||||||
|
if(ptr == nullptr) {
|
||||||
|
std::cerr << "terminate called without an active exception\n";
|
||||||
|
print_terminate_trace();
|
||||||
|
} else {
|
||||||
|
std::rethrow_exception(ptr);
|
||||||
|
}
|
||||||
} catch(cpptrace::exception& e) {
|
} catch(cpptrace::exception& e) {
|
||||||
std::cerr << "Terminate called after throwing an instance of "
|
std::cerr << "Terminate called after throwing an instance of "
|
||||||
<< cpptrace::demangle(typeid(e).name())
|
<< demangle(typeid(e).name())
|
||||||
<< ": "
|
<< ": "
|
||||||
<< e.get_raw_what()
|
<< e.get_raw_what()
|
||||||
<< '\n';
|
<< '\n';
|
||||||
e.get_trace().print(std::cerr, cpptrace::isatty(cpptrace::stderr_fileno));
|
e.get_trace().print(std::cerr, isatty(stderr_fileno));
|
||||||
} catch(std::exception& e) {
|
} catch(std::exception& e) {
|
||||||
std::cerr << "Terminate called after throwing an instance of "
|
std::cerr << "Terminate called after throwing an instance of "
|
||||||
<< cpptrace::demangle(typeid(e).name())
|
<< demangle(typeid(e).name())
|
||||||
<< ": "
|
<< ": "
|
||||||
<< e.what()
|
<< e.what()
|
||||||
<< '\n';
|
<< '\n';
|
||||||
|
print_terminate_trace();
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
std::cerr << "Terminate called after throwing an instance of "
|
std::cerr << "Terminate called after throwing an instance of "
|
||||||
<< detail::exception_type_name()
|
<< detail::exception_type_name()
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
print_terminate_trace();
|
||||||
}
|
}
|
||||||
|
std::flush(std::cerr);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user