debug/system: make last-chance printing more reliable
This commit is contained in:
parent
928cdb4e8b
commit
af01ba0836
@ -9,6 +9,7 @@
|
||||
#include "./system.hpp"
|
||||
|
||||
#include "debugger.hpp"
|
||||
#include "except.hpp"
|
||||
|
||||
#include "../backtrace.hpp"
|
||||
#include "../log.hpp"
|
||||
@ -17,15 +18,24 @@
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static std::terminate_handler old_handler = nullptr;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
static void abort_with_trace (void)
|
||||
{
|
||||
// Manually trigger a breakpoint if possible so that the debugger won't
|
||||
// silently dump us some place without further information.
|
||||
// eg, CLion/GDB/Win32 silently dropping us out of the session.
|
||||
// We used to trigger a breakpoint so that our debugger didn't just let the
|
||||
// child terminate (ie, the behaviour of CLion/Win32/GDB).
|
||||
//
|
||||
// But this might silently terminate the program instead of allowing us the
|
||||
// chance to dump a backtrace depending on the precise mechanism for
|
||||
// `breakpoint`; in particular SIGTRAP and SIGINT trigger this.
|
||||
#if 0
|
||||
breakpoint ();
|
||||
#endif
|
||||
|
||||
// If this is because of an exception we may as well rethrow and hope that
|
||||
// the system will print exception data during the abort process.
|
||||
// If we're here because of an exception we may as well rethrow and hope
|
||||
// that the system will print exception data during the abort process.
|
||||
//
|
||||
// But we can at least try to print anything derived from std::exception
|
||||
// (which is a likely guess) before we self-destruct.
|
||||
@ -34,22 +44,28 @@ static void abort_with_trace (void)
|
||||
std::rethrow_exception (ptr);
|
||||
} catch (std::exception const &x) {
|
||||
LOG_EMERGENCY ("unhandled exception: %!\n%!", x.what (), ::cruft::backtrace {});
|
||||
} catch (cruft::error const &x) {
|
||||
LOG_EMERGENCY ("unhandled exception: %!\n%!", x, ::cruft::backtrace {});
|
||||
} catch (...) {
|
||||
LOG_EMERGENCY ("unhandled exception: %!\n", ::cruft::backtrace {});
|
||||
LOG_EMERGENCY ("unhandled exception\n%!", ::cruft::backtrace {});
|
||||
}
|
||||
} else {
|
||||
LOG_EMERGENCY ("aborting: %!", ::cruft::backtrace {});
|
||||
}
|
||||
|
||||
std::abort ();
|
||||
old_handler ();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
cruft::debug::init [[gnu::constructor]] (void)
|
||||
cruft::debug::init (void)
|
||||
{
|
||||
std::set_terminate (abort_with_trace);
|
||||
old_handler = std::set_terminate (abort_with_trace);
|
||||
CHECK_NEQ (
|
||||
reinterpret_cast<void*> (old_handler),
|
||||
reinterpret_cast<void*> (abort_with_trace)
|
||||
);
|
||||
|
||||
if (!debug_enabled && !getenv ("DEBUG"))
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user