1
0
Fork 0

Fix #8860: [Win32] Crashlog window wasn't reliably shown for crashes not on the main thread.

pull/8862/head
Michael Lutz 2021-03-13 21:34:51 +01:00
parent 062eeb9810
commit 13011e00c6
5 changed files with 46 additions and 23 deletions

View File

@ -114,6 +114,12 @@ public:
*/ */
static void InitialiseCrashLog(); 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 SetErrorMessage(const char *message);
static void AfterCrashLogCleanup(); static void AfterCrashLogCleanup();
}; };

View File

@ -257,3 +257,7 @@ void CDECL HandleCrash(int signum)
signal(*i, HandleCrash); signal(*i, HandleCrash);
} }
} }
/* static */ void CrashLog::InitThread()
{
}

View File

@ -181,3 +181,7 @@ static void CDECL HandleCrash(int signum)
signal(*i, HandleCrash); signal(*i, HandleCrash);
} }
} }
/* static */ void CrashLog::InitThread()
{
}

View File

@ -537,7 +537,7 @@ static void ShowCrashlogWindow();
* Stack pointer for use when 'starting' the crash handler. * Stack pointer for use when 'starting' the crash handler.
* Not static as gcc's inline assembly needs it that way. * 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) static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep)
{ {
@ -604,6 +604,19 @@ static void CDECL CustomAbort(int signal)
} }
/* static */ void CrashLog::InitialiseCrashLog() /* 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) #if defined(_M_AMD64) || defined(_M_ARM64)
CONTEXT ctx; CONTEXT ctx;
@ -619,22 +632,16 @@ static void CDECL CustomAbort(int signal)
_safe_esp = (void *)(ctx.Rsp - 8); _safe_esp = (void *)(ctx.Rsp - 8);
# endif # endif
#else #else
void *safe_esp;
# if defined(_MSC_VER) # if defined(_MSC_VER)
_asm { _asm {
mov _safe_esp, esp mov safe_esp, esp
} }
# else # else
asm("movl %esp, __safe_esp"); asm("movl %esp, _safe_esp");
# endif # endif
_safe_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);
#endif
SetUnhandledExceptionFilter(ExceptionHandler);
} }
/* The crash log GUI */ /* The crash log GUI */

View File

@ -11,6 +11,7 @@
#define THREAD_H #define THREAD_H
#include "debug.h" #include "debug.h"
#include "crashlog.h"
#include <system_error> #include <system_error>
#include <thread> #include <thread>
@ -47,6 +48,7 @@ inline bool StartNewThread(std::thread *thr, const char *name, TFn&& _Fx, TArgs&
try { try {
std::thread t([] (const char *name, TFn&& F, TArgs&&... A) { std::thread t([] (const char *name, TFn&& F, TArgs&&... A) {
SetCurrentThreadName(name); SetCurrentThreadName(name);
CrashLog::InitThread();
try { try {
/* Call user function with the given arguments. */ /* Call user function with the given arguments. */
F(A...); F(A...);