Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions backward.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,10 @@
#include <mutex>
#include <thread>

#ifdef BACKWARD_ATLEAST_CXX11
#include <atomic>
#endif

#include <basetsd.h>

#ifdef _WIN64
Expand Down Expand Up @@ -4393,6 +4397,18 @@ class SignalHandling {
}

private:
#ifdef BACKWARD_ATLEAST_CXX11
// Re-entrancy guard: ensure we only handle a crash once.
static std::atomic<bool> &handling_in_progress() {
static std::atomic<bool> flag{false};
return flag;
}

static bool begin_handling_once() {
bool expected = false;
return handling_in_progress().compare_exchange_strong(expected, true, std::memory_order_acq_rel);
}
#endif
static CONTEXT *ctx() {
static CONTEXT data;
return &data;
Expand Down Expand Up @@ -4442,11 +4458,21 @@ class SignalHandling {
}

static inline void terminator() {
#ifdef BACKWARD_ATLEAST_CXX11
if (!begin_handling_once()) {
return;
}
#endif
crash_handler(signal_skip_recs);
abort();
}

static inline void signal_handler(int) {
#ifdef BACKWARD_ATLEAST_CXX11
if (!begin_handling_once()) {
return;
}
#endif
crash_handler(signal_skip_recs);
abort();
}
Expand All @@ -4456,11 +4482,22 @@ class SignalHandling {
const wchar_t *,
unsigned int,
uintptr_t) {
#ifdef BACKWARD_ATLEAST_CXX11
if (!begin_handling_once()) {
return;
}
#endif
crash_handler(signal_skip_recs);
abort();
}

NOINLINE static LONG WINAPI crash_handler(EXCEPTION_POINTERS *info) {
#ifdef BACKWARD_ATLEAST_CXX11
// Only the first crash should be processed.
if (!begin_handling_once()) {
return EXCEPTION_CONTINUE_SEARCH;
}
#endif
// The exception info supplies a trace from exactly where the issue was,
// no need to skip records
crash_handler(0, info->ContextRecord);
Expand Down