Remove Windows signal handling for now, as it's causing issues.
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
efe902d045
commit
8fecd2079a
|
@ -2,8 +2,8 @@
|
||||||
#define ARBUTILS_SIGNALHANDLING_HPP
|
#define ARBUTILS_SIGNALHANDLING_HPP
|
||||||
#if PRETTYTRACES && !WINDOWS
|
#if PRETTYTRACES && !WINDOWS
|
||||||
#define BACKWARD_HAS_DW 1
|
#define BACKWARD_HAS_DW 1
|
||||||
#endif
|
|
||||||
#include "../extern/backward.hpp"
|
#include "../extern/backward.hpp"
|
||||||
|
#endif
|
||||||
#include "Exception.hpp"
|
#include "Exception.hpp"
|
||||||
|
|
||||||
// Sourced from https://github.com/bombela/backward-cpp/blob/master/backward.hpp#L3849
|
// Sourced from https://github.com/bombela/backward-cpp/blob/master/backward.hpp#L3849
|
||||||
|
@ -150,180 +150,6 @@ namespace ArbUt {
|
||||||
|
|
||||||
#endif // BACKWARD_SYSTEM_LINUX || BACKWARD_SYSTEM_DARWIN
|
#endif // BACKWARD_SYSTEM_LINUX || BACKWARD_SYSTEM_DARWIN
|
||||||
|
|
||||||
#ifdef BACKWARD_SYSTEM_WINDOWS
|
|
||||||
|
|
||||||
class SignalHandling {
|
|
||||||
public:
|
|
||||||
SignalHandling(void(callback)(const char*) = nullptr, const std::vector<int>& = std::vector<int>())
|
|
||||||
: reporter_thread_([]() {
|
|
||||||
/* We handle crashes in a utility thread:
|
|
||||||
backward structures and some Windows functions called here
|
|
||||||
need stack space, which we do not have when we encounter a
|
|
||||||
stack overflow.
|
|
||||||
To support reporting stack traces during a stack overflow,
|
|
||||||
we create a utility thread at startup, which waits until a
|
|
||||||
crash happens or the program exits normally. */
|
|
||||||
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lk(mtx());
|
|
||||||
cv().wait(lk, [] { return crashed() != crash_status::running; });
|
|
||||||
}
|
|
||||||
if (crashed() == crash_status::crashed) {
|
|
||||||
handle_stacktrace(skip_recs());
|
|
||||||
}
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lk(mtx());
|
|
||||||
crashed() = crash_status::ending;
|
|
||||||
}
|
|
||||||
cv().notify_one();
|
|
||||||
}) {
|
|
||||||
SetUnhandledExceptionFilter(crash_handler);
|
|
||||||
_callback = callback;
|
|
||||||
|
|
||||||
signal(SIGABRT, signal_handler);
|
|
||||||
_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
|
|
||||||
|
|
||||||
std::set_terminate(&terminator);
|
|
||||||
std::set_unexpected(&terminator);
|
|
||||||
_set_purecall_handler(&terminator);
|
|
||||||
_set_invalid_parameter_handler(&invalid_parameter_handler);
|
|
||||||
}
|
|
||||||
bool loaded() const { return true; }
|
|
||||||
|
|
||||||
~SignalHandling() {
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lk(mtx());
|
|
||||||
crashed() = crash_status::normal_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
cv().notify_one();
|
|
||||||
|
|
||||||
reporter_thread_.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetCallback(void (*callback)(const char*)) { _callback = callback; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
static void (*_callback)(const char*);
|
|
||||||
|
|
||||||
static CONTEXT* ctx() {
|
|
||||||
static CONTEXT data;
|
|
||||||
return &data;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class crash_status { running, crashed, normal_exit, ending };
|
|
||||||
|
|
||||||
static crash_status& crashed() {
|
|
||||||
static crash_status data;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::mutex& mtx() {
|
|
||||||
static std::mutex data;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::condition_variable& cv() {
|
|
||||||
static std::condition_variable data;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HANDLE& thread_handle() {
|
|
||||||
static HANDLE handle;
|
|
||||||
return handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::thread reporter_thread_;
|
|
||||||
|
|
||||||
// TODO: how not to hardcode these?
|
|
||||||
static const constexpr int signal_skip_recs =
|
|
||||||
#ifdef __clang__
|
|
||||||
// With clang, RtlCaptureContext also captures the stack frame of the
|
|
||||||
// current function Below that, there ar 3 internal Windows functions
|
|
||||||
4
|
|
||||||
#else
|
|
||||||
// With MSVC cl, RtlCaptureContext misses the stack frame of the current
|
|
||||||
// function The first entries during StackWalk are the 3 internal Windows
|
|
||||||
// functions
|
|
||||||
3
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
|
|
||||||
static int& skip_recs() {
|
|
||||||
static int data;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void terminator() {
|
|
||||||
crash_handler(signal_skip_recs);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void signal_handler(int) {
|
|
||||||
crash_handler(signal_skip_recs);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void __cdecl invalid_parameter_handler(const wchar_t*, const wchar_t*, const wchar_t*,
|
|
||||||
unsigned int, uintptr_t) {
|
|
||||||
crash_handler(signal_skip_recs);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
NOINLINE static LONG WINAPI crash_handler(EXCEPTION_POINTERS* info) {
|
|
||||||
// The exception info supplies a trace from exactly where the issue was,
|
|
||||||
// no need to skip records
|
|
||||||
crash_handler(0, info->ContextRecord);
|
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
NOINLINE static void crash_handler(int skip, CONTEXT* ct = nullptr) {
|
|
||||||
|
|
||||||
if (ct == nullptr) {
|
|
||||||
RtlCaptureContext(ctx());
|
|
||||||
} else {
|
|
||||||
memcpy(ctx(), ct, sizeof(CONTEXT));
|
|
||||||
}
|
|
||||||
DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &thread_handle(), 0, FALSE,
|
|
||||||
DUPLICATE_SAME_ACCESS);
|
|
||||||
|
|
||||||
skip_recs() = skip;
|
|
||||||
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lk(mtx());
|
|
||||||
crashed() = crash_status::crashed;
|
|
||||||
}
|
|
||||||
|
|
||||||
cv().notify_one();
|
|
||||||
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lk(mtx());
|
|
||||||
cv().wait(lk, [] { return crashed() != crash_status::crashed; });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_stacktrace(int skip_frames = 0) {
|
|
||||||
// printer creates the TraceResolver, which can supply us a machine type
|
|
||||||
// for stack walking. Without this, StackTrace can only guess using some
|
|
||||||
// macros.
|
|
||||||
// StackTrace also requires that the PDBs are already loaded, which is done
|
|
||||||
// in the constructor of TraceResolver
|
|
||||||
backward::Printer printer;
|
|
||||||
|
|
||||||
backward::StackTrace st;
|
|
||||||
st.set_machine_type(printer.resolver().machine_type());
|
|
||||||
st.set_context(ctx());
|
|
||||||
st.set_thread_handle(thread_handle());
|
|
||||||
st.load_here(32 + skip_frames);
|
|
||||||
st.skip_n_firsts(skip_frames);
|
|
||||||
|
|
||||||
printer.address = true;
|
|
||||||
printer.print(st, std::cerr);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // BACKWARD_SYSTEM_WINDOWS
|
|
||||||
|
|
||||||
#ifdef BACKWARD_SYSTEM_UNKNOWN
|
#ifdef BACKWARD_SYSTEM_UNKNOWN
|
||||||
|
|
||||||
class SignalHandling {
|
class SignalHandling {
|
||||||
|
|
Loading…
Reference in New Issue