diff options
-rw-r--r-- | src/crashlog.h | 6 | ||||
-rw-r--r-- | src/os/macosx/crashlog_osx.cpp | 4 | ||||
-rw-r--r-- | src/os/unix/crashlog_unix.cpp | 4 | ||||
-rw-r--r-- | src/os/windows/crashlog_win.cpp | 41 | ||||
-rw-r--r-- | src/thread.h | 2 |
5 files changed, 40 insertions, 17 deletions
diff --git a/src/crashlog.h b/src/crashlog.h index 7f1ff47ed..7d15c3512 100644 --- a/src/crashlog.h +++ b/src/crashlog.h @@ -114,6 +114,12 @@ public: */ static void InitialiseCrashLog(); + /** + * Prepare crash log handler for a newly started thread. + * @note must be implemented by all implementers of CrashLog. + */ + static void InitThread(); + static void SetErrorMessage(const char *message); static void AfterCrashLogCleanup(); }; diff --git a/src/os/macosx/crashlog_osx.cpp b/src/os/macosx/crashlog_osx.cpp index a1470b6d6..7fcb672a8 100644 --- a/src/os/macosx/crashlog_osx.cpp +++ b/src/os/macosx/crashlog_osx.cpp @@ -257,3 +257,7 @@ void CDECL HandleCrash(int signum) signal(*i, HandleCrash); } } + +/* static */ void CrashLog::InitThread() +{ +} diff --git a/src/os/unix/crashlog_unix.cpp b/src/os/unix/crashlog_unix.cpp index ee3f5823f..fc3682d02 100644 --- a/src/os/unix/crashlog_unix.cpp +++ b/src/os/unix/crashlog_unix.cpp @@ -181,3 +181,7 @@ static void CDECL HandleCrash(int signum) signal(*i, HandleCrash); } } + +/* static */ void CrashLog::InitThread() +{ +} diff --git a/src/os/windows/crashlog_win.cpp b/src/os/windows/crashlog_win.cpp index b0667ad8f..76a05eaa9 100644 --- a/src/os/windows/crashlog_win.cpp +++ b/src/os/windows/crashlog_win.cpp @@ -537,7 +537,7 @@ 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) { @@ -605,6 +605,19 @@ static void CDECL CustomAbort(int signal) /* static */ void CrashLog::InitialiseCrashLog() { + 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); +} + +/* static */ void CrashLog::InitThread() +{ #if defined(_M_AMD64) || defined(_M_ARM64) CONTEXT ctx; RtlCaptureContext(&ctx); @@ -613,28 +626,22 @@ static void CDECL CustomAbort(int signal) * 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); -#endif +# endif #else -#if defined(_MSC_VER) + void *safe_esp; +# if defined(_MSC_VER) _asm { - mov _safe_esp, esp + mov safe_esp, esp } -#else - asm("movl %esp, __safe_esp"); -#endif -#endif - - /* 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); +# else + asm("movl %esp, _safe_esp"); +# endif + _safe_esp = safe_esp; #endif - SetUnhandledExceptionFilter(ExceptionHandler); } /* The crash log GUI */ diff --git a/src/thread.h b/src/thread.h index f45694930..f2a47e7bf 100644 --- a/src/thread.h +++ b/src/thread.h @@ -11,6 +11,7 @@ #define THREAD_H #include "debug.h" +#include "crashlog.h" #include <system_error> #include <thread> @@ -47,6 +48,7 @@ inline bool StartNewThread(std::thread *thr, const char *name, TFn&& _Fx, TArgs& try { std::thread t([] (const char *name, TFn&& F, TArgs&&... A) { SetCurrentThreadName(name); + CrashLog::InitThread(); try { /* Call user function with the given arguments. */ F(A...); |