@@ -111,11 +111,17 @@ public:
* Initialiser for crash logs; do the appropriate things so crashes are
* handled by our crash handler instead of returning straight to the OS.
* @note must be implemented by all implementers of CrashLog.
*/
static void InitialiseCrashLog();
/**
* Prepare crash log handler for a newly started thread.
static void InitThread();
static void SetErrorMessage(const char *message);
static void AfterCrashLogCleanup();
};
#endif /* CRASHLOG_H */
@@ -254,6 +254,10 @@ void CDECL HandleCrash(int signum)
/* static */ void CrashLog::InitialiseCrashLog()
{
for (const int *i = _signals_to_handle; i != endof(_signals_to_handle); i++) {
signal(*i, HandleCrash);
}
/* static */ void CrashLog::InitThread()
@@ -178,6 +178,10 @@ static void CDECL HandleCrash(int signum
@@ -534,13 +534,13 @@ extern bool CloseConsoleLogIfActive();
static void ShowCrashlogWindow();
* Stack pointer for use when 'starting' the crash handler.
* Not static as gcc's inline assembly needs it that way.
void *_safe_esp = nullptr;
thread_local void *_safe_esp = nullptr;
static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep)
/* Restore system timer resolution. */
timeEndPeriod(1);
@@ -602,42 +602,49 @@ static void CDECL CustomAbort(int signal
RaiseException(0xE1212012, 0, 0, nullptr);
CrashLog::InitThread();
/* SIGABRT is not an unhandled exception, so we need to intercept it. */
signal(SIGABRT, CustomAbort);
#if defined(_MSC_VER)
/* Don't show abort message as we will get the crashlog window anyway. */
_set_abort_behavior(0, _WRITE_ABORT_MSG);
#endif
SetUnhandledExceptionFilter(ExceptionHandler);
#if defined(_M_AMD64) || defined(_M_ARM64)
CONTEXT ctx;
RtlCaptureContext(&ctx);
/* The stack pointer for AMD64 must always be 16-byte aligned inside a
* function. As we are simulating a function call with the safe ESP value,
* we need to subtract 8 for the imaginary return address otherwise stack
* alignment would be wrong in the called function. */
#if defined(_M_ARM64)
# if defined(_M_ARM64)
_safe_esp = (void *)(ctx.Sp - 8);
#else
# else
_safe_esp = (void *)(ctx.Rsp - 8);
_asm {
mov _safe_esp, esp
# endif
asm("movl %esp, __safe_esp");
void *safe_esp;
# if defined(_MSC_VER)
mov safe_esp, esp
asm("movl %esp, _safe_esp");
_safe_esp = safe_esp;
/* The crash log GUI */
static bool _expanded;
@@ -8,12 +8,13 @@
/** @file thread.h Base of all threads. */
#ifndef THREAD_H
#define THREAD_H
#include "debug.h"
#include "crashlog.h"
#include <system_error>
#include <thread>
* Sleep on the current thread for a defined time.
* @param milliseconds Time to sleep for in milliseconds.
@@ -44,12 +45,13 @@ template<class TFn, class... TArgs>
inline bool StartNewThread(std::thread *thr, const char *name, TFn&& _Fx, TArgs&&... _Ax)
#ifndef NO_THREADS
try {
std::thread t([] (const char *name, TFn&& F, TArgs&&... A) {
SetCurrentThreadName(name);
/* Call user function with the given arguments. */
F(A...);
} catch (...) {
NOT_REACHED();
Status change: