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 42 insertions and 19 deletions:
0 comments (0 inline, 0 general)
src/crashlog.h
Show inline comments
 
@@ -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();
 
};
src/os/macosx/crashlog_osx.cpp
Show inline comments
 
@@ -257,3 +257,7 @@ void CDECL HandleCrash(int signum)
 
		signal(*i, HandleCrash);
 
	}
 
}
 

	
 
/* static */ void CrashLog::InitThread()
 
{
 
}
src/os/unix/crashlog_unix.cpp
Show inline comments
 
@@ -181,3 +181,7 @@ static void CDECL HandleCrash(int signum
 
		signal(*i, HandleCrash);
 
	}
 
}
 

	
 
/* static */ void CrashLog::InitThread()
 
{
 
}
src/os/windows/crashlog_win.cpp
Show inline comments
 
@@ -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
 
#else
 
#if defined(_MSC_VER)
 
	_asm {
 
		mov _safe_esp, esp
 
	}
 
#	endif
 
#else
 
	asm("movl %esp, __safe_esp");
 
#endif
 
	void *safe_esp;
 
#	if defined(_MSC_VER)
 
	_asm {
 
		mov safe_esp, esp
 
	}
 
#	else
 
	asm("movl %esp, _safe_esp");
 
#	endif
 
	_safe_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);
 
#endif
 
	SetUnhandledExceptionFilter(ExceptionHandler);
 
}
 

	
 
/* The crash log GUI */
src/thread.h
Show inline comments
 
@@ -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 *
 
	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...);
0 comments (0 inline, 0 general)