Changeset - r25047:a8e131d1e25b
[Not reviewed]
master
0 5 0
Michael Lutz - 4 years ago 2021-03-13 20:34:51
michi@icosahedron.de
Fix #8860: [Win32] Crashlog window wasn't reliably shown for crashes not on the main thread.
5 files changed with 34 insertions and 11 deletions:
0 comments (0 inline, 0 general)
src/crashlog.h
Show inline comments
 
@@ -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.
 
	 * @note must be implemented by all implementers of CrashLog.
 
	 */
 
	static void InitThread();
 

	
 
	static void SetErrorMessage(const char *message);
 
	static void AfterCrashLogCleanup();
 
};
 

	
 
#endif /* CRASHLOG_H */
src/os/macosx/crashlog_osx.cpp
Show inline comments
 
@@ -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()
 
{
 
}
src/os/unix/crashlog_unix.cpp
Show inline comments
 
@@ -178,6 +178,10 @@ static 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()
 
{
 
}
src/os/windows/crashlog_win.cpp
Show inline comments
 
@@ -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,12 +602,25 @@ static void CDECL CustomAbort(int signal
 
{
 
	RaiseException(0xE1212012, 0, 0, nullptr);
 
}
 

	
 
/* 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);
 

	
 
	/* 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,
 
@@ -616,28 +629,22 @@ static void CDECL CustomAbort(int signal
 
#if defined(_M_ARM64)
 
	_safe_esp = (void *)(ctx.Sp - 8);
 
#else
 
	_safe_esp = (void *)(ctx.Rsp - 8);
 
#endif
 
#else
 
	void *safe_esp;
 
#if defined(_MSC_VER)
 
	_asm {
 
		mov _safe_esp, esp
 
		mov safe_esp, esp
 
	}
 
#else
 
	asm("movl %esp, __safe_esp");
 
#endif
 
	asm("movl %esp, _safe_esp");
 
#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);
 
	_safe_esp = safe_esp;
 
#endif
 
	SetUnhandledExceptionFilter(ExceptionHandler);
 
}
 

	
 
/* The crash log GUI */
 

	
 
static bool _expanded;
 

	
src/thread.h
Show inline comments
 
@@ -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);
 
				CrashLog::InitThread();
 
				try {
 
					/* Call user function with the given arguments. */
 
					F(A...);
 
				} catch (...) {
 
					NOT_REACHED();
 
				}
0 comments (0 inline, 0 general)