CrashHandler: Include assertion/panic information in dumps

This commit is contained in:
Stenzek 2025-04-04 19:59:30 +10:00
parent b3087657be
commit c75d5f71b7
No known key found for this signature in database
3 changed files with 20 additions and 19 deletions

View File

@ -82,7 +82,7 @@ extern "C" __attribute__((weak)) void android_set_abort_message(const char*);
{ {
#ifndef __ANDROID__ #ifndef __ANDROID__
std::fputs(szMsg, stderr); std::fputs(szMsg, stderr);
CrashHandler::WriteDumpForCaller(); CrashHandler::WriteDumpForCaller(szMsg);
std::fputs("Aborting application.\n", stderr); std::fputs("Aborting application.\n", stderr);
std::fflush(stderr); std::fflush(stderr);
std::abort(); std::abort();
@ -121,7 +121,7 @@ void Y_OnAssertFailed(const char* szMessage, const char* szFunction, const char*
} }
else if (result != IDIGNORE) else if (result != IDIGNORE)
{ {
CrashHandler::WriteDumpForCaller(); CrashHandler::WriteDumpForCaller(szMsg);
TerminateProcess(GetCurrentProcess(), 0xBAADC0DE); TerminateProcess(GetCurrentProcess(), 0xBAADC0DE);
} }
@ -153,7 +153,7 @@ void Y_OnAssertFailed(const char* szMessage, const char* szFunction, const char*
if (result == IDOK) if (result == IDOK)
__debugbreak(); __debugbreak();
else else
CrashHandler::WriteDumpForCaller(); CrashHandler::WriteDumpForCaller(szMsg);
TerminateProcess(GetCurrentProcess(), 0xBAADC0DE); TerminateProcess(GetCurrentProcess(), 0xBAADC0DE);

View File

@ -100,7 +100,7 @@ static void GenerateCrashFilename(wchar_t* buf, size_t len, const wchar_t* prefi
extension); extension);
} }
static void WriteMinidumpAndCallstack(PEXCEPTION_POINTERS exi) static void WriteMinidumpAndCallstack(PEXCEPTION_POINTERS exi, const std::string_view message)
{ {
wchar_t filename[1024] = {}; wchar_t filename[1024] = {};
GenerateCrashFilename(filename, std::size(filename), s_write_directory.empty() ? nullptr : s_write_directory.c_str(), GenerateCrashFilename(filename, std::size(filename), s_write_directory.empty() ? nullptr : s_write_directory.c_str(),
@ -108,13 +108,13 @@ static void WriteMinidumpAndCallstack(PEXCEPTION_POINTERS exi)
// might fail // might fail
HANDLE hFile = CreateFileW(filename, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, nullptr); HANDLE hFile = CreateFileW(filename, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, nullptr);
if (exi && hFile != INVALID_HANDLE_VALUE) DWORD written;
if (!message.empty() && hFile != INVALID_HANDLE_VALUE)
{ {
char line[1024]; const char newline = '\n';
DWORD written; WriteFile(hFile, message.data(), static_cast<DWORD>(message.length()), &written, nullptr);
std::snprintf(line, std::size(line), "Exception 0x%08X at 0x%p\n", WriteFile(hFile, &newline, sizeof(newline), &written, nullptr);
static_cast<unsigned>(exi->ExceptionRecord->ExceptionCode), exi->ExceptionRecord->ExceptionAddress);
WriteFile(hFile, line, static_cast<DWORD>(std::strlen(line)), &written, nullptr);
} }
GenerateCrashFilename(filename, std::size(filename), s_write_directory.empty() ? nullptr : s_write_directory.c_str(), GenerateCrashFilename(filename, std::size(filename), s_write_directory.empty() ? nullptr : s_write_directory.c_str(),
@ -130,10 +130,7 @@ static void WriteMinidumpAndCallstack(PEXCEPTION_POINTERS exi)
{ {
static const char error_message[] = "Failed to write minidump file.\n"; static const char error_message[] = "Failed to write minidump file.\n";
if (hFile != INVALID_HANDLE_VALUE) if (hFile != INVALID_HANDLE_VALUE)
{
DWORD written;
WriteFile(hFile, error_message, sizeof(error_message) - 1, &written, nullptr); WriteFile(hFile, error_message, sizeof(error_message) - 1, &written, nullptr);
}
} }
if (hMinidumpFile != INVALID_HANDLE_VALUE) if (hMinidumpFile != INVALID_HANDLE_VALUE)
CloseHandle(hMinidumpFile); CloseHandle(hMinidumpFile);
@ -154,7 +151,11 @@ static LONG NTAPI ExceptionHandler(PEXCEPTION_POINTERS exi)
if (s_cleanup_handler) if (s_cleanup_handler)
s_cleanup_handler(); s_cleanup_handler();
WriteMinidumpAndCallstack(exi); char message[128];
std::snprintf(message, std::size(message), "Exception 0x%08X at 0x%p",
static_cast<unsigned>(exi->ExceptionRecord->ExceptionCode), exi->ExceptionRecord->ExceptionAddress);
WriteMinidumpAndCallstack(exi, message);
} }
// returning EXCEPTION_CONTINUE_SEARCH makes sense, except for the fact that it seems to leave zombie processes // returning EXCEPTION_CONTINUE_SEARCH makes sense, except for the fact that it seems to leave zombie processes
@ -181,9 +182,9 @@ void CrashHandler::SetWriteDirectory(std::string_view dump_directory)
s_write_directory = StringUtil::UTF8StringToWideString(dump_directory); s_write_directory = StringUtil::UTF8StringToWideString(dump_directory);
} }
void CrashHandler::WriteDumpForCaller() void CrashHandler::WriteDumpForCaller(std::string_view message)
{ {
WriteMinidumpAndCallstack(nullptr); WriteMinidumpAndCallstack(nullptr, message);
} }
#elif !defined(__APPLE__) && !defined(__ANDROID__) #elif !defined(__APPLE__) && !defined(__ANDROID__)
@ -364,7 +365,7 @@ void CrashHandler::SetWriteDirectory(std::string_view dump_directory)
{ {
} }
void CrashHandler::WriteDumpForCaller() void CrashHandler::WriteDumpForCaller(std::string_view message)
{ {
LogCallstack(0, nullptr); LogCallstack(0, nullptr);
} }
@ -380,7 +381,7 @@ void CrashHandler::SetWriteDirectory(std::string_view dump_directory)
{ {
} }
void CrashHandler::WriteDumpForCaller() void CrashHandler::WriteDumpForCaller(std::string_view message)
{ {
} }

View File

@ -18,7 +18,7 @@ using CleanupHandler = void(*)();
bool Install(CleanupHandler cleanup_handler); bool Install(CleanupHandler cleanup_handler);
void SetWriteDirectory(std::string_view dump_directory); void SetWriteDirectory(std::string_view dump_directory);
void WriteDumpForCaller(); void WriteDumpForCaller(std::string_view message);
#ifndef _WIN32 #ifndef _WIN32