- Add the game log to the crash report. I don't know why I didn't think to do this sooner.

Since we're already sending everything to a rich edit control hidden in the background,
  we can just grab its contents for the report.
- Use code page 1252 when previewing text files in the crash dialog.

SVN r2185 (trunk)
This commit is contained in:
Randy Heit 2010-03-04 02:17:34 +00:00
parent dfde55d249
commit 0ebace4883
2 changed files with 89 additions and 16 deletions

View file

@ -503,6 +503,71 @@ void __cdecl Writef (HANDLE file, const char *format, ...)
WriteFile (file, buffer, len, &len, NULL); WriteFile (file, buffer, len, &len, NULL);
} }
//==========================================================================
//
// WriteLogFileStreamer
//
// The callback function to stream a Rich Edit's contents to a file.
//
//==========================================================================
static DWORD CALLBACK WriteLogFileStreamer(DWORD_PTR cookie, LPBYTE buffer, LONG cb, LONG *pcb)
{
DWORD didwrite;
LONG p, pp;
// Replace gray foreground color with black.
static const char *badfg = "\\red223\\green223\\blue223;";
// 4321098 765432109 876543210
// 2 1 0
for (p = pp = 0; p < cb; ++p)
{
if (buffer[p] == badfg[pp])
{
++pp;
if (pp == 25)
{
buffer[p - 1] = buffer[p - 2] = buffer[p - 3] =
buffer[p - 9] = buffer[p -10] = buffer[p -11] =
buffer[p -18] = buffer[p -19] = buffer[p -20] = '0';
break;
}
}
else
{
pp = 0;
}
}
if (!WriteFile((HANDLE)cookie, buffer, cb, &didwrite, NULL))
{
return 1;
}
*pcb = didwrite;
return 0;
}
//==========================================================================
//
// WriteLogFile
//
// Writes the contents of a Rich Edit control to a file.
//
//==========================================================================
HANDLE WriteLogFile(HWND edit)
{
HANDLE file;
file = CreateTempFile();
if (file != INVALID_HANDLE_VALUE)
{
EDITSTREAM streamer = { (DWORD_PTR)file, 0, WriteLogFileStreamer };
SendMessage(edit, EM_STREAMOUT, SF_RTF, (LPARAM)&streamer);
}
return file;
}
//========================================================================== //==========================================================================
// //
// CreateCrashLog // CreateCrashLog
@ -511,7 +576,7 @@ void __cdecl Writef (HANDLE file, const char *format, ...)
// //
//========================================================================== //==========================================================================
void CreateCrashLog (char *custominfo, DWORD customsize) void CreateCrashLog (char *custominfo, DWORD customsize, HWND richlog)
{ {
// Do not collect information more than once. // Do not collect information more than once.
if (NumFiles != 0) if (NumFiles != 0)
@ -561,6 +626,10 @@ void CreateCrashLog (char *custominfo, DWORD customsize)
AddFile (file, "local.txt"); AddFile (file, "local.txt");
} }
} }
if (richlog != NULL)
{
AddFile (WriteLogFile(richlog), "log.rtf");
}
CloseHandle (DbgProcess); CloseHandle (DbgProcess);
} }
@ -1984,7 +2053,6 @@ static INT_PTR CALLBACK CrashDlgProc (HWND hDlg, UINT message, WPARAM wParam, LP
static INT_PTR CALLBACK DetailsDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) static INT_PTR CALLBACK DetailsDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{ {
HGDIOBJ font;
HWND ctrl; HWND ctrl;
int i, j; int i, j;
@ -1996,15 +2064,9 @@ static INT_PTR CALLBACK DetailsDlgProc (HWND hDlg, UINT message, WPARAM wParam,
pEnableThemeDialogTexture (hDlg, ETDT_ENABLETAB); pEnableThemeDialogTexture (hDlg, ETDT_ENABLETAB);
} }
// Set up the file contents display: Use a fixed width font, // Set up the file contents display: No undos. The control's
// no undos. The control's userdata stores the index of the // userdata stores the index of the file currently displayed.
// file currently displayed.
ctrl = GetDlgItem (hDlg, IDC_CRASHFILECONTENTS); ctrl = GetDlgItem (hDlg, IDC_CRASHFILECONTENTS);
font = GetStockObject (ANSI_FIXED_FONT);
if (font != INVALID_HANDLE_VALUE)
{
SendMessage (ctrl, WM_SETFONT, (WPARAM)font, FALSE);
}
SendMessage (ctrl, EM_SETUNDOLIMIT, 0, 0); SendMessage (ctrl, EM_SETUNDOLIMIT, 0, 0);
SetWindowLongPtr (ctrl, GWLP_USERDATA, -1); SetWindowLongPtr (ctrl, GWLP_USERDATA, -1);
SetEditControl (ctrl, GetDlgItem(hDlg, IDC_CRASHFILESIZE), 0); SetEditControl (ctrl, GetDlgItem(hDlg, IDC_CRASHFILESIZE), 0);
@ -2178,6 +2240,8 @@ static void SetEditControl (HWND edit, HWND sizedisplay, int filenum)
EDITSTREAM stream; EDITSTREAM stream;
DWORD size; DWORD size;
POINT pt = { 0, 0 }; POINT pt = { 0, 0 };
const char *rtf = NULL;
HGDIOBJ font;
// Don't refresh the control if it's already showing the file we want. // Don't refresh the control if it's already showing the file we want.
if (GetWindowLongPtr (edit, GWLP_USERDATA) == filenum) if (GetWindowLongPtr (edit, GWLP_USERDATA) == filenum)
@ -2201,10 +2265,19 @@ static void SetEditControl (HWND edit, HWND sizedisplay, int filenum)
SetFilePointer (TarFiles[filenum].File, 0, NULL, FILE_BEGIN); SetFilePointer (TarFiles[filenum].File, 0, NULL, FILE_BEGIN);
SendMessage (edit, EM_SETSCROLLPOS, 0, (LPARAM)&pt); SendMessage (edit, EM_SETSCROLLPOS, 0, (LPARAM)&pt);
// Set the font now, in case log.rtf was previously viewed, because
// that file changes it.
font = GetStockObject (ANSI_FIXED_FONT);
if (font != INVALID_HANDLE_VALUE)
{
SendMessage (edit, WM_SETFONT, (WPARAM)font, FALSE);
}
// Text files are streamed in as-is. // Text files are streamed in as-is.
// Binary files are streamed in as color-coded hex dumps. // Binary files are streamed in as color-coded hex dumps.
stream.dwError = 0; stream.dwError = 0;
if (strstr (TarFiles[filenum].Filename, ".txt") != NULL) if (strstr (TarFiles[filenum].Filename, ".txt") != NULL ||
(rtf = strstr (TarFiles[filenum].Filename, ".rtf")) != NULL)
{ {
CHARFORMAT beBlack; CHARFORMAT beBlack;
@ -2215,7 +2288,7 @@ static void SetEditControl (HWND edit, HWND sizedisplay, int filenum)
SendMessage (edit, EM_SETCHARFORMAT, 0, (LPARAM)&beBlack); SendMessage (edit, EM_SETCHARFORMAT, 0, (LPARAM)&beBlack);
stream.dwCookie = (DWORD_PTR)TarFiles[filenum].File; stream.dwCookie = (DWORD_PTR)TarFiles[filenum].File;
stream.pfnCallback = StreamEditText; stream.pfnCallback = StreamEditText;
SendMessage (edit, EM_STREAMIN, SF_TEXT, (LPARAM)&stream); SendMessage (edit, EM_STREAMIN, rtf ? SF_RTF : SF_TEXT | SF_USECODEPAGE | (1252 << 16), (LPARAM)&stream);
} }
else else
{ {

View file

@ -105,7 +105,7 @@
// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
void CreateCrashLog (char *custominfo, DWORD customsize); void CreateCrashLog (char *custominfo, DWORD customsize, HWND richedit);
void DisplayCrashLog (); void DisplayCrashLog ();
extern BYTE *ST_Util_BitsForBitmap (BITMAPINFO *bitmap_info); extern BYTE *ST_Util_BitsForBitmap (BITMAPINFO *bitmap_info);
@ -1176,7 +1176,7 @@ LONG WINAPI CatchAllExceptions (LPEXCEPTION_POINTERS info)
CrashPointers = *info; CrashPointers = *info;
DoomSpecificInfo (custominfo, 16384); DoomSpecificInfo (custominfo, 16384);
CreateCrashLog (custominfo, (DWORD)strlen(custominfo)); CreateCrashLog (custominfo, (DWORD)strlen(custominfo), ConWindow);
// If the main thread crashed, then make it clean up after itself. // If the main thread crashed, then make it clean up after itself.
// Otherwise, put the crashing thread to sleep and signal the main thread to clean up. // Otherwise, put the crashing thread to sleep and signal the main thread to clean up.
@ -1248,7 +1248,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n
*(int *)0 = 0; *(int *)0 = 0;
} }
__except(CrashPointers = *GetExceptionInformation(), __except(CrashPointers = *GetExceptionInformation(),
CreateCrashLog (__argv[1], 9), EXCEPTION_EXECUTE_HANDLER) CreateCrashLog (__argv[1], 9, NULL), EXCEPTION_EXECUTE_HANDLER)
{ {
} }
DisplayCrashLog (); DisplayCrashLog ();
@ -1261,7 +1261,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n
infiniterecursion(1); infiniterecursion(1);
} }
__except(CrashPointers = *GetExceptionInformation(), __except(CrashPointers = *GetExceptionInformation(),
CreateCrashLog (__argv[1], 14), EXCEPTION_EXECUTE_HANDLER) CreateCrashLog (__argv[1], 14, NULL), EXCEPTION_EXECUTE_HANDLER)
{ {
} }
DisplayCrashLog (); DisplayCrashLog ();