- fixed the crash reporter on Windows.

This commit is contained in:
Christoph Oelckers 2020-02-02 13:30:26 +01:00
parent a890079906
commit 1bb1f2ae98
5 changed files with 54 additions and 48 deletions

View file

@ -1022,22 +1022,22 @@ install(TARGETS ${PROJECT_NAME}
COMPONENT "Game executable") COMPONENT "Game executable")
source_group("Utility" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/utility/.+") source_group("Utility" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/utility/.+")
source_group("Code" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/.+") source_group("Core" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/.+")
source_group("Code\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/textures/.+") source_group("Core\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/textures/.+")
source_group("Code\\Textures\\Formats" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/textures/formats/.+") source_group("Core\\Textures\\Formats" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/textures/formats/.+")
source_group("Code\\Utility" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/utility/.+") source_group("Core\\Utility" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/utility/.+")
source_group("Code\\2D" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/2d/.+") source_group("Core\\2D" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/2d/.+")
source_group("Code\\Console" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/console/.+") source_group("Core\\Console" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/console/.+")
source_group("Code\\Fonts" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/fonts/.+") source_group("Core\\Fonts" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/fonts/.+")
source_group("Code\\File System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/filesystem/.+") source_group("Core\\File System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/filesystem/.+")
source_group("Code\\Music" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/music/.+") source_group("Core\\Music" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/music/.+")
source_group("Code\\Sound" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/sound/.+") source_group("Core\\Sound" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/sound/.+")
source_group("Code\\Sound\\Backend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/sound/backend/.+") source_group("Core\\Sound\\Backend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/sound/backend/.+")
source_group("Code\\DObject" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/dobject/.+") source_group("Core\\DObject" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/dobject/.+")
source_group("Code\\Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/menu/.+") source_group("Core\\Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/menu/.+")
source_group("Code\\Rendering" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/rendering/.+") source_group("Core\\Rendering" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/rendering/.+")
source_group("Code\\Rendering\\GL_Load" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/rendering/gl_load/.+") source_group("Core\\Rendering\\GL_Load" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/rendering/gl_load/.+")
source_group("Code\\Rendering\\GL\\System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/rendering/gl/system.+") source_group("Core\\Rendering\\GL\\System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/rendering/gl/system.+")
source_group("Platform" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/.+") source_group("Platform" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/.+")
source_group("Platform\\Win32" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/win32/.+") source_group("Platform\\Win32" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/win32/.+")
source_group("Platform\\POSIX" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/posix/.+") source_group("Platform\\POSIX" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/platform/posix/.+")

View file

@ -1,17 +1,20 @@
#pragma once #pragma once
// This header collects all things printf.
// EDuke32 had two totally separate output paths and all the added code from G/ZDoom uses yet another means.
// Everything goes to the console now, but to avoid changing everything, this redirects all output to the console, with the proper settings.
// Changing all this would mean altering over 1000 lines of code which would add a needless complication to merging from upstream.
#if defined __GNUC__ || defined __clang__ #if defined __GNUC__ || defined __clang__
# define ATTRIBUTE(attrlist) __attribute__(attrlist) # define ATTRIBUTE(attrlist) __attribute__(attrlist)
#else #else
# define ATTRIBUTE(attrlist) # define ATTRIBUTE(attrlist)
#endif #endif
// This header collects all things printf.
// EDuke32 had two totally separate output paths and all the added code from G/ZDoom uses yet another means.
// Everything goes to the console now, but to avoid changing everything, this redirects all output to the console, with the proper settings.
// Changing all this would mean altering over 1000 lines of code which would add a needless complication to merging from upstream.
extern "C" int mysnprintf(char* buffer, size_t count, const char* format, ...) ATTRIBUTE((format(printf, 3, 4)));
extern "C" int myvsnprintf(char* buffer, size_t count, const char* format, va_list argptr) ATTRIBUTE((format(printf, 3, 0)));
// game print flags // game print flags
enum enum
{ {

View file

@ -476,3 +476,4 @@ struct StringNoCaseHashTraits
// Compares two keys, returning zero if they are the same. // Compares two keys, returning zero if they are the same.
int Compare(const FString& left, const FString& right) { return left.CompareNoCase(right); } int Compare(const FString& left, const FString& right) { return left.CompareNoCase(right); }
}; };

View file

@ -41,16 +41,16 @@ const char *GetVersionString();
/** Lots of different version numbers **/ /** Lots of different version numbers **/
#define VERSIONSTR "0.3.3" #define VERSIONSTR "0.3.4"
// The version as seen in the Windows resource // The version as seen in the Windows resource
#define RC_FILEVERSION 0,3,3,0 #define RC_FILEVERSION 0,3,4,0
#define RC_PRODUCTVERSION 0,3,3,0 #define RC_PRODUCTVERSION 0,3,4,0
#define RC_PRODUCTVERSION2 VERSIONSTR #define RC_PRODUCTVERSION2 VERSIONSTR
// These are for content versioning. // These are for content versioning.
#define VER_MAJOR 0 #define VER_MAJOR 0
#define VER_MINOR 3 #define VER_MINOR 3
#define VER_REVISION 3 #define VER_REVISION 4
// More stuff that needs to be different for derivatives. // More stuff that needs to be different for derivatives.
#define GAMENAME "Raze" #define GAMENAME "Raze"

View file

@ -62,6 +62,7 @@
#include "m_swap.h" #include "m_swap.h"
#include "basics.h" #include "basics.h"
#include "zstring.h" #include "zstring.h"
#include "printf.h"
#include <time.h> #include <time.h>
#include <zlib.h> #include <zlib.h>
@ -429,7 +430,7 @@ void Writef (HANDLE file, const char *format, ...)
DWORD len; DWORD len;
va_start (args, format); va_start (args, format);
len = snprintf (buffer, sizeof buffer, format, args); len = myvsnprintf (buffer, sizeof buffer, format, args);
va_end (args); va_end (args);
WriteFile (file, buffer, len, &len, NULL); WriteFile (file, buffer, len, &len, NULL);
} }
@ -649,16 +650,16 @@ HANDLE WriteTextReport ()
break; break;
} }
} }
j = snprintf (CrashSummary, countof(CrashSummary), "Code: %08lX", CrashPointers.ExceptionRecord->ExceptionCode); j = mysnprintf (CrashSummary, countof(CrashSummary), "Code: %08lX", CrashPointers.ExceptionRecord->ExceptionCode);
if ((size_t)i < sizeof(exceptions)/sizeof(exceptions[0])) if ((size_t)i < sizeof(exceptions)/sizeof(exceptions[0]))
{ {
j += snprintf (CrashSummary + j, countof(CrashSummary) - j, " (%s", exceptions[i].Text); j += mysnprintf (CrashSummary + j, countof(CrashSummary) - j, " (%s", exceptions[i].Text);
if (CrashPointers.ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) if (CrashPointers.ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
{ {
// Pre-NT kernels do not seem to provide this information. // Pre-NT kernels do not seem to provide this information.
if (verinfo.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) if (verinfo.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)
{ {
j += snprintf (CrashSummary + j, countof(CrashSummary) - j, j += mysnprintf (CrashSummary + j, countof(CrashSummary) - j,
" - tried to %s address %p", " - tried to %s address %p",
CrashPointers.ExceptionRecord->ExceptionInformation[0] ? "write" : "read", CrashPointers.ExceptionRecord->ExceptionInformation[0] ? "write" : "read",
(void *)CrashPointers.ExceptionRecord->ExceptionInformation[1]); (void *)CrashPointers.ExceptionRecord->ExceptionInformation[1]);
@ -666,7 +667,7 @@ HANDLE WriteTextReport ()
} }
CrashSummary[j++] = ')'; CrashSummary[j++] = ')';
} }
j += snprintf (CrashSummary + j, countof(CrashSummary) - j, "\r\nAddress: %p", CrashPointers.ExceptionRecord->ExceptionAddress); j += mysnprintf (CrashSummary + j, countof(CrashSummary) - j, "\r\nAddress: %p", CrashPointers.ExceptionRecord->ExceptionAddress);
Writef (file, "%s\r\nFlags: %08X\r\n\r\n", CrashSummary, CrashPointers.ExceptionRecord->ExceptionFlags); Writef (file, "%s\r\nFlags: %08X\r\n\r\n", CrashSummary, CrashPointers.ExceptionRecord->ExceptionFlags);
Writef (file, "Windows %s %d.%d Build %d %s\r\n\r\n", Writef (file, "Windows %s %d.%d Build %d %s\r\n\r\n",
@ -803,8 +804,8 @@ static void AddToolHelp (HANDLE file)
pCreateToolhelp32Snapshot = (CREATESNAPSHOT)GetProcAddress (kernel, "CreateToolhelp32Snapshot"); pCreateToolhelp32Snapshot = (CREATESNAPSHOT)GetProcAddress (kernel, "CreateToolhelp32Snapshot");
pThread32First = (THREADWALK)GetProcAddress (kernel, "Thread32First"); pThread32First = (THREADWALK)GetProcAddress (kernel, "Thread32First");
pThread32Next = (THREADWALK)GetProcAddress (kernel, "Thread32Next"); pThread32Next = (THREADWALK)GetProcAddress (kernel, "Thread32Next");
pModule32First = (MODULEWALK)GetProcAddress (kernel, "Module32First"); pModule32First = (MODULEWALK)GetProcAddress (kernel, "Module32FirstW");
pModule32Next = (MODULEWALK)GetProcAddress (kernel, "Module32Next"); pModule32Next = (MODULEWALK)GetProcAddress (kernel, "Module32NextW");
if (!(pCreateToolhelp32Snapshot && pThread32First && pThread32Next && if (!(pCreateToolhelp32Snapshot && pThread32First && pThread32Next &&
pModule32First && pModule32Next)) pModule32First && pModule32Next))
@ -849,12 +850,13 @@ static void AddToolHelp (HANDLE file)
{ {
do do
{ {
auto amod = FString(module.szModule);
Writef (file, "%p - %p %c%s\r\n", Writef (file, "%p - %p %c%s\r\n",
module.modBaseAddr, module.modBaseAddr + module.modBaseSize - 1, module.modBaseAddr, module.modBaseAddr + module.modBaseSize - 1,
module.modBaseAddr <= CrashPointers.ExceptionRecord->ExceptionAddress && module.modBaseAddr <= CrashPointers.ExceptionRecord->ExceptionAddress &&
module.modBaseAddr + module.modBaseSize > CrashPointers.ExceptionRecord->ExceptionAddress module.modBaseAddr + module.modBaseSize > CrashPointers.ExceptionRecord->ExceptionAddress
? '*' : ' ', ? '*' : ' ',
module.szModule); amod.GetChars());
} while (pModule32Next (snapshot, &module)); } while (pModule32Next (snapshot, &module));
} }
@ -1301,15 +1303,15 @@ static void DumpBytes (HANDLE file, uint8_t *address)
{ {
if ((i & 15) == 0) if ((i & 15) == 0)
{ {
line_p += snprintf (line_p, countof(line) - (line_p - line), "\r\n%p:", address); line_p += mysnprintf (line_p, countof(line) - (line_p - line), "\r\n%p:", address);
} }
if (SafeReadMemory (address, &peek, 1)) if (SafeReadMemory (address, &peek, 1))
{ {
line_p += snprintf (line_p, countof(line) - (line_p - line), " %02x", *address); line_p += mysnprintf (line_p, countof(line) - (line_p - line), " %02x", *address);
} }
else else
{ {
line_p += snprintf (line_p, countof(line) - (line_p - line), " --"); line_p += mysnprintf (line_p, countof(line) - (line_p - line), " --");
} }
address++; address++;
} }
@ -2065,7 +2067,7 @@ repeat:
switch (info->Stage) switch (info->Stage)
{ {
case 0: // Write prologue case 0: // Write prologue
buff_p += snprintf (buff_p, buff_end - buff_p, "{\\rtf1\\ansi\\deff0" buff_p += mysnprintf (buff_p, buff_end - buff_p, "{\\rtf1\\ansi\\deff0"
"{\\colortbl ;\\red0\\green0\\blue80;\\red0\\green0\\blue0;\\red80\\green0\\blue80;}" "{\\colortbl ;\\red0\\green0\\blue80;\\red0\\green0\\blue0;\\red80\\green0\\blue80;}"
"\\viewkind4\\pard"); "\\viewkind4\\pard");
info->Stage++; info->Stage++;
@ -2081,7 +2083,7 @@ repeat:
goto repeat; goto repeat;
} }
char *linestart = buff_p; char *linestart = buff_p;
buff_p += snprintf (buff_p, buff_end - buff_p, "\\cf1 %08lx:\\cf2 ", info->Pointer); buff_p += mysnprintf (buff_p, buff_end - buff_p, "\\cf1 %08lx:\\cf2 ", info->Pointer);
info->Pointer += read; info->Pointer += read;
for (i = 0; i < read;) for (i = 0; i < read;)
@ -2090,12 +2092,12 @@ repeat:
{ {
DWORD d; DWORD d;
memcpy(&d, &buf16[i], sizeof(d)); memcpy(&d, &buf16[i], sizeof(d));
buff_p += snprintf (buff_p, buff_end - buff_p, " %08lx", d); buff_p += mysnprintf (buff_p, buff_end - buff_p, " %08lx", d);
i += 4; i += 4;
} }
else else
{ {
buff_p += snprintf (buff_p, buff_end - buff_p, " %02x", buf16[i]); buff_p += mysnprintf (buff_p, buff_end - buff_p, " %02x", buf16[i]);
i += 1; i += 1;
} }
} }
@ -2103,7 +2105,7 @@ repeat:
{ {
*buff_p++ = ' '; *buff_p++ = ' ';
} }
buff_p += snprintf (buff_p, buff_end - buff_p, "\\cf3 "); buff_p += mysnprintf (buff_p, buff_end - buff_p, "\\cf3 ");
for (i = 0; i < read; ++i) for (i = 0; i < read; ++i)
{ {
uint8_t code = buf16[i]; uint8_t code = buf16[i];
@ -2111,17 +2113,17 @@ repeat:
if (code == '\\' || code == '{' || code == '}') *buff_p++ = '\\'; if (code == '\\' || code == '{' || code == '}') *buff_p++ = '\\';
*buff_p++ = code; *buff_p++ = code;
} }
buff_p += snprintf (buff_p, buff_end - buff_p, "\\par\r\n"); buff_p += mysnprintf (buff_p, buff_end - buff_p, "\\par\r\n");
} }
break; break;
case 2: // Write epilogue case 2: // Write epilogue
buff_p += snprintf (buff_p, buff_end - buff_p, "\\cf0 }"); buff_p += mysnprintf (buff_p, buff_end - buff_p, "\\cf0 }");
info->Stage = 4; info->Stage = 4;
break; break;
case 3: // Write epilogue for truncated file case 3: // Write epilogue for truncated file
buff_p += snprintf (buff_p, buff_end - buff_p, "--- Rest of file truncated ---\\cf0 }"); buff_p += mysnprintf (buff_p, buff_end - buff_p, "--- Rest of file truncated ---\\cf0 }");
info->Stage = 4; info->Stage = 4;
break; break;
@ -2161,11 +2163,11 @@ static void SetEditControl (HWND edit, HWND sizedisplay, int filenum)
size = GetFileSize (TarFiles[filenum].File, NULL); size = GetFileSize (TarFiles[filenum].File, NULL);
if (size < 1024) if (size < 1024)
{ {
snprintf (sizebuf, countof(sizebuf), "(%lu bytes)", size); mysnprintf (sizebuf, countof(sizebuf), "(%lu bytes)", size);
} }
else else
{ {
snprintf (sizebuf, countof(sizebuf), "(%lu KB)", size/1024); mysnprintf (sizebuf, countof(sizebuf), "(%lu KB)", size/1024);
} }
SetWindowTextA (sizedisplay, sizebuf); SetWindowTextA (sizedisplay, sizebuf);
@ -2289,7 +2291,7 @@ void DisplayCrashLog ()
GAMENAME" crashed but was unable to produce\n" GAMENAME" crashed but was unable to produce\n"
"detailed information about the crash.\n" "detailed information about the crash.\n"
"\nThis is all that is available:\n\nCode=XXXXXXXX\nAddr=XXXXXXXX"; "\nThis is all that is available:\n\nCode=XXXXXXXX\nAddr=XXXXXXXX";
snprintf (ohPoo + countof(ohPoo) - 23, 23, "%08lX\nAddr=%p", CrashCode, CrashAddress); mysnprintf (ohPoo + countof(ohPoo) - 23, 23, "%08lX\nAddr=%p", CrashCode, CrashAddress);
MessageBoxA (NULL, ohPoo, GAMENAME" Very Fatal Error", MB_OK|MB_ICONSTOP); MessageBoxA (NULL, ohPoo, GAMENAME" Very Fatal Error", MB_OK|MB_ICONSTOP);
if (WinHlp32 != NULL) if (WinHlp32 != NULL)
{ {