Remove the disassembler. It's never been useful, and it's a lot of code--
a lot of extra room for error in code we really want to be robust (the error handler). Remove "crashdump.dat". It was only useful for tracing crashes in the disassembler.
This commit is contained in:
+11
-19
@@ -55,32 +55,24 @@ BEGIN
|
|||||||
SS_CENTERIMAGE
|
SS_CENTERIMAGE
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_DISASM_CRASH DIALOG 0, 0, 399, 271
|
IDD_DISASM_CRASH DIALOGEX 0, 0, 399, 151
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION
|
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION
|
||||||
CAPTION "StepMania Error"
|
CAPTION "StepMania Error"
|
||||||
FONT 8, "MS Sans Serif"
|
FONT 8, "MS Sans Serif", 0, 0, 0x0
|
||||||
BEGIN
|
BEGIN
|
||||||
DEFPUSHBUTTON "Close",IDC_BUTTON_CLOSE,348,255,50,15
|
DEFPUSHBUTTON "Close",IDC_BUTTON_CLOSE,348,135,50,15
|
||||||
LTEXT "crash reason: programmer needs good whack on head",
|
LTEXT "crash reason: programmer needs good whack on head",
|
||||||
IDC_STATIC_BOMBREASON,8,240,219,8
|
IDC_STATIC_BOMBREASON,8,120,219,8
|
||||||
PUSHBUTTON "View Log",IDC_VIEW_LOG,1,255,70,15
|
PUSHBUTTON "View Log",IDC_VIEW_LOG,1,135,70,15
|
||||||
PUSHBUTTON "View crash dump",IDC_CRASH_SAVE,75,255,70,15
|
PUSHBUTTON "View crash dump",IDC_CRASH_SAVE,75,135,70,15
|
||||||
PUSHBUTTON "Report the Error",IDC_BUTTON_REPORT,210,255,76,15
|
PUSHBUTTON "Report the Error",IDC_BUTTON_REPORT,210,135,76,15
|
||||||
PUSHBUTTON "Restart",IDC_BUTTON_RESTART,348,238,50,15
|
PUSHBUTTON "Restart",IDC_BUTTON_RESTART,348,118,50,15
|
||||||
CONTROL 121,IDC_STATIC,"Static",SS_BITMAP,1,2,396,36
|
CONTROL 121,IDC_STATIC,"Static",SS_BITMAP,1,2,396,36
|
||||||
LTEXT "StepMania has crashed due to a program error. Diagnostic information has been saved to a file called ""crashinfo.txt"" in the StepMania program directory. Hit ""View crash dump"" to view it. Please include this file in all bug reports.",
|
LTEXT "StepMania has crashed due to a program error. Diagnostic information has been saved to a file called ""crashinfo.txt"" in the StepMania program directory. Hit ""View crash dump"" to view it. Please include this file in all bug reports.",
|
||||||
IDC_STATIC,8,41,382,19
|
IDC_STATIC,8,41,382,19
|
||||||
LTEXT "Program disassembly",IDC_STATIC,7,64,66,8
|
LISTBOX IDC_CALL_STACK,7,76,391,38,LBS_NOINTEGRALHEIGHT |
|
||||||
LISTBOX IDC_ASMBOX,7,76,279,101,LBS_OWNERDRAWVARIABLE |
|
|
||||||
LBS_USETABSTOPS | LBS_NOINTEGRALHEIGHT | LBS_NODATA |
|
|
||||||
LBS_NOSEL | WS_VSCROLL | WS_TABSTOP
|
|
||||||
LISTBOX IDC_CALL_STACK,7,196,279,38,LBS_NOINTEGRALHEIGHT |
|
|
||||||
WS_VSCROLL | WS_TABSTOP
|
WS_VSCROLL | WS_TABSTOP
|
||||||
LTEXT "CPU registers",IDC_STATIC,292,64,44,8
|
LTEXT "Estimated call stack",IDC_STATIC,7,64,64,8
|
||||||
LISTBOX IDC_REGDUMP,291,76,101,158,NOT LBS_NOTIFY |
|
|
||||||
LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_VSCROLL |
|
|
||||||
WS_HSCROLL | WS_TABSTOP
|
|
||||||
LTEXT "Estimated call stack",IDC_STATIC,7,184,64,8
|
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_OK DIALOG 0, 0, 318, 87
|
IDD_OK DIALOG 0, 0, 318, 87
|
||||||
@@ -119,7 +111,7 @@ BEGIN
|
|||||||
LEFTMARGIN, 1
|
LEFTMARGIN, 1
|
||||||
RIGHTMARGIN, 398
|
RIGHTMARGIN, 398
|
||||||
VERTGUIDE, 286
|
VERTGUIDE, 286
|
||||||
BOTTOMMARGIN, 270
|
BOTTOMMARGIN, 150
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_OK, DIALOG
|
IDD_OK, DIALOG
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "crash.h"
|
#include "crash.h"
|
||||||
#include "disasm.h"
|
|
||||||
#include "CrashList.h"
|
#include "CrashList.h"
|
||||||
#include "ProductInfo.h"
|
#include "ProductInfo.h"
|
||||||
|
|
||||||
@@ -36,6 +35,8 @@
|
|||||||
|
|
||||||
#include "GotoURL.h"
|
#include "GotoURL.h"
|
||||||
|
|
||||||
|
static HFONT hFontMono = NULL;
|
||||||
|
|
||||||
static void DoSave(const EXCEPTION_POINTERS *pExc);
|
static void DoSave(const EXCEPTION_POINTERS *pExc);
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
@@ -47,7 +48,34 @@ static void DoSave(const EXCEPTION_POINTERS *pExc);
|
|||||||
extern HINSTANCE g_hInstance;
|
extern HINSTANCE g_hInstance;
|
||||||
extern unsigned long version_num;
|
extern unsigned long version_num;
|
||||||
|
|
||||||
static CodeDisassemblyWindow *g_pcdw;
|
|
||||||
|
|
||||||
|
extern HINSTANCE g_hInstance;
|
||||||
|
|
||||||
|
// WARNING: This is called from crash-time conditions! No malloc() or new!!!
|
||||||
|
|
||||||
|
#define malloc not_allowed_here
|
||||||
|
#define new not_allowed_here
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void SpliceProgramPath(char *buf, int bufsiz, const char *fn) {
|
||||||
|
char tbuf[MAX_PATH];
|
||||||
|
char *pszFile;
|
||||||
|
|
||||||
|
GetModuleFileName(NULL, tbuf, sizeof tbuf);
|
||||||
|
GetFullPathName(tbuf, bufsiz, buf, &pszFile);
|
||||||
|
strcpy(pszFile, fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct VDDebugInfoContext {
|
struct VDDebugInfoContext {
|
||||||
void *pRawBlock;
|
void *pRawBlock;
|
||||||
@@ -66,89 +94,8 @@ struct VDDebugInfoContext {
|
|||||||
|
|
||||||
static VDDebugInfoContext g_debugInfo;
|
static VDDebugInfoContext g_debugInfo;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
BOOL APIENTRY CrashDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
BOOL APIENTRY CrashDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||||
static void ReportCrashLog(HWND hwnd, HANDLE hFile);
|
|
||||||
static void ReportStaticLog(HWND hwnd, HANDLE hFile);
|
|
||||||
static void ReportAdditionalLog(HWND hwnd, HANDLE hFile);
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
/*
|
|
||||||
void checkfpustack(const char *file, const int line) throw() {
|
|
||||||
static const char szFPUProblemCaption[]="FPU/MMX internal problem";
|
|
||||||
static const char szFPUProblemMessage[]="The FPU stack wasn't empty! Tagword = %04x\nFile: %s, line %d";
|
|
||||||
static bool seenmsg=false;
|
|
||||||
|
|
||||||
char buf[128];
|
|
||||||
unsigned short tagword;
|
|
||||||
|
|
||||||
if (seenmsg)
|
|
||||||
return;
|
|
||||||
|
|
||||||
__asm fnstenv buf
|
|
||||||
|
|
||||||
tagword = *(unsigned short *)(buf + 8);
|
|
||||||
|
|
||||||
if (tagword != 0xffff) {
|
|
||||||
wsprintf(buf, szFPUProblemMessage, tagword, file, line);
|
|
||||||
MessageBox(NULL, buf, szFPUProblemCaption, MB_OK);
|
|
||||||
seenmsg=true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void __declspec(naked) *operator new(size_t bytes) {
|
|
||||||
static const char fname[]="stack trace";
|
|
||||||
|
|
||||||
__asm {
|
|
||||||
push ebp
|
|
||||||
mov ebp,esp
|
|
||||||
|
|
||||||
push [ebp+4] ;return address
|
|
||||||
push offset fname ;'filename'
|
|
||||||
push _NORMAL_BLOCK ;block type
|
|
||||||
push [ebp+8] ;allocation size
|
|
||||||
|
|
||||||
call _malloc_dbg
|
|
||||||
add esp,16
|
|
||||||
|
|
||||||
pop ebp
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
void __declspec(naked) stackcheck(void *&sp) {
|
|
||||||
static const char g_szStackHemorrhage[]="WARNING: Thread is hemorrhaging stack space!\n";
|
|
||||||
|
|
||||||
__asm {
|
|
||||||
mov eax,[esp+4]
|
|
||||||
mov ecx,[eax]
|
|
||||||
or ecx,ecx
|
|
||||||
jnz started
|
|
||||||
mov [eax],esp
|
|
||||||
ret
|
|
||||||
started:
|
|
||||||
sub ecx,esp
|
|
||||||
mov eax,ecx
|
|
||||||
sar ecx,31
|
|
||||||
xor eax,ecx
|
|
||||||
sub eax,ecx
|
|
||||||
cmp eax,128
|
|
||||||
jb ok
|
|
||||||
push offset g_szStackHemorrhage
|
|
||||||
call dword ptr [OutputDebugString]
|
|
||||||
int 3
|
|
||||||
ok:
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@@ -236,42 +183,6 @@ bool VDDebugInfoInitFromMemory(VDDebugInfoContext *pctx, const void *_src);
|
|||||||
bool VDDebugInfoInitFromFile(VDDebugInfoContext *pctx, const char *pszFilename);
|
bool VDDebugInfoInitFromFile(VDDebugInfoContext *pctx, const char *pszFilename);
|
||||||
void VDDebugInfoDeinit(VDDebugInfoContext *pctx);
|
void VDDebugInfoDeinit(VDDebugInfoContext *pctx);
|
||||||
|
|
||||||
static void SpliceProgramPath(char *buf, int bufsiz, const char *fn) {
|
|
||||||
char tbuf[MAX_PATH];
|
|
||||||
char *pszFile;
|
|
||||||
|
|
||||||
GetModuleFileName(NULL, tbuf, sizeof tbuf);
|
|
||||||
GetFullPathName(tbuf, bufsiz, buf, &pszFile);
|
|
||||||
strcpy(pszFile, fn);
|
|
||||||
}
|
|
||||||
|
|
||||||
long CrashSymLookup(VDDisassemblyContext *pctx, unsigned long virtAddr, char *buf, int buf_len) {
|
|
||||||
if (!g_debugInfo.pRVAHeap)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return VDDebugInfoLookupRVA(&g_debugInfo, virtAddr, buf, buf_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char szEmergencyDumpName[MAX_PATH];
|
|
||||||
static void DoSaveEmergencyDump(const char *buf, int siz) {
|
|
||||||
HANDLE hFile;
|
|
||||||
|
|
||||||
SpliceProgramPath(szEmergencyDumpName, sizeof szEmergencyDumpName, "crashdump.dat");
|
|
||||||
hFile = CreateFile(szEmergencyDumpName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
if (INVALID_HANDLE_VALUE == hFile)
|
|
||||||
return;
|
|
||||||
|
|
||||||
DWORD dwActual;
|
|
||||||
WriteFile(hFile, buf, siz, &dwActual, NULL);
|
|
||||||
FlushFileBuffers(hFile);
|
|
||||||
|
|
||||||
CloseHandle(hFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DoEraseEmergencyDump()
|
|
||||||
{
|
|
||||||
DeleteFile(szEmergencyDumpName);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern HWND g_hWndMain;
|
extern HWND g_hWndMain;
|
||||||
long __stdcall CrashHandler(EXCEPTION_POINTERS *pExc)
|
long __stdcall CrashHandler(EXCEPTION_POINTERS *pExc)
|
||||||
@@ -332,17 +243,12 @@ long __stdcall CrashHandler(EXCEPTION_POINTERS *pExc)
|
|||||||
if(InHere)
|
if(InHere)
|
||||||
{
|
{
|
||||||
/* If we get here, then we've been called recursively, which means
|
/* If we get here, then we've been called recursively, which means
|
||||||
* we (the disassembler or related code) crashed. If this happens,
|
* we crashed.
|
||||||
* we're not in very good shape. We've left the emergency dump;
|
*/
|
||||||
* that's all we have to go by. Tell this to the user, and then die.
|
|
||||||
*
|
|
||||||
* We've already blown up twice, and this is our last line of defense.
|
|
||||||
* If this dies, we have nothing, so keep it simple. */
|
|
||||||
SetUnhandledExceptionFilter(NULL);
|
SetUnhandledExceptionFilter(NULL);
|
||||||
MessageBox( NULL,
|
MessageBox( NULL,
|
||||||
"The error reporting interface has crashed.\n"
|
"The error reporting interface has crashed.\n",
|
||||||
"Please report a bug and attach the file \"crashdump.dat\"\n"
|
"Fatal Error", MB_OK );
|
||||||
"to the report.", "Fatal Error", MB_OK );
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DebugBreak();
|
DebugBreak();
|
||||||
#endif
|
#endif
|
||||||
@@ -352,52 +258,31 @@ long __stdcall CrashHandler(EXCEPTION_POINTERS *pExc)
|
|||||||
InHere=true;
|
InHere=true;
|
||||||
/////////////////////////
|
/////////////////////////
|
||||||
|
|
||||||
static char buf[CODE_WINDOW+16];
|
hFontMono = CreateFont(
|
||||||
HANDLE hprMe = GetCurrentProcess();
|
10, // nHeight
|
||||||
void *lpBaseAddress = pExc->ExceptionRecord->ExceptionAddress;
|
0, // nWidth
|
||||||
char *lpAddr = (char *)((long)lpBaseAddress & -32);
|
0, // nEscapement
|
||||||
|
0, // nOrientation
|
||||||
|
FW_DONTCARE, // fnWeight
|
||||||
|
FALSE, // fdwItalic
|
||||||
|
FALSE, // fdwUnderline
|
||||||
|
FALSE, // fdwStrikeOut
|
||||||
|
ANSI_CHARSET, // fdwCharSet
|
||||||
|
OUT_DEFAULT_PRECIS, // fdwOutputPrecision
|
||||||
|
CLIP_DEFAULT_PRECIS, // fdwClipPrecision
|
||||||
|
DEFAULT_QUALITY, // fdwQuality
|
||||||
|
DEFAULT_PITCH | FF_DONTCARE, // fdwPitchAndFamily
|
||||||
|
"Lucida Console"
|
||||||
|
);
|
||||||
|
|
||||||
memset(buf, 0, sizeof buf);
|
if (!hFontMono)
|
||||||
|
hFontMono = (HFONT)GetStockObject(ANSI_FIXED_FONT);
|
||||||
if ((unsigned long)lpAddr > CODE_WINDOW/2)
|
|
||||||
lpAddr -= CODE_WINDOW/2;
|
|
||||||
else
|
|
||||||
lpAddr = NULL;
|
|
||||||
|
|
||||||
if (!ReadProcessMemory(hprMe, lpAddr, buf, CODE_WINDOW, NULL)) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i=0; i<CODE_WINDOW; i+=32)
|
|
||||||
if (!ReadProcessMemory(hprMe, lpAddr+i, buf+i, 32, NULL))
|
|
||||||
memset(buf+i, 0, 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
DoSaveEmergencyDump(buf, CODE_WINDOW);
|
|
||||||
|
|
||||||
CodeDisassemblyWindow cdw(buf, CODE_WINDOW, (char *)(buf-lpAddr), lpAddr);
|
|
||||||
|
|
||||||
g_pcdw = &cdw;
|
|
||||||
|
|
||||||
cdw.setFaultAddress(lpBaseAddress);
|
|
||||||
|
|
||||||
// Attempt to read debug file.
|
// Attempt to read debug file.
|
||||||
|
|
||||||
bool bSuccess;
|
char buf[1024];
|
||||||
|
|
||||||
if (cdw.vdc.pExtraData) {
|
|
||||||
bSuccess = VDDebugInfoInitFromMemory(&g_debugInfo, cdw.vdc.pExtraData);
|
|
||||||
} else {
|
|
||||||
SpliceProgramPath(buf, sizeof buf, "StepMania.vdi");
|
SpliceProgramPath(buf, sizeof buf, "StepMania.vdi");
|
||||||
bSuccess = VDDebugInfoInitFromFile(&g_debugInfo, buf);
|
VDDebugInfoInitFromFile(&g_debugInfo, buf);
|
||||||
if (!bSuccess) {
|
|
||||||
SpliceProgramPath(buf, sizeof buf, "StepMani.vdi");
|
|
||||||
bSuccess = VDDebugInfoInitFromFile(&g_debugInfo, buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cdw.vdc.pSymLookup = CrashSymLookup;
|
|
||||||
|
|
||||||
cdw.parse();
|
|
||||||
|
|
||||||
/* In case something goes amiss before the user can view the crash
|
/* In case something goes amiss before the user can view the crash
|
||||||
* dump, save it now. */
|
* dump, save it now. */
|
||||||
@@ -418,8 +303,6 @@ long __stdcall CrashHandler(EXCEPTION_POINTERS *pExc)
|
|||||||
|
|
||||||
VDDebugInfoDeinit(&g_debugInfo);
|
VDDebugInfoDeinit(&g_debugInfo);
|
||||||
|
|
||||||
/* We've made it. Delete the emergency dump. */
|
|
||||||
DoEraseEmergencyDump();
|
|
||||||
InHere = false;
|
InHere = false;
|
||||||
|
|
||||||
SetUnhandledExceptionFilter(NULL);
|
SetUnhandledExceptionFilter(NULL);
|
||||||
@@ -460,36 +343,6 @@ static void SetWindowTitlef(HWND hwnd, const char *format, ...) {
|
|||||||
SetWindowText(hwnd, buf);
|
SetWindowText(hwnd, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ReportCrashData(HWND hwnd, HWND hwndReason, HANDLE hFile, const EXCEPTION_POINTERS *const pExc) {
|
|
||||||
// const EXCEPTION_RECORD *const pRecord = (const EXCEPTION_RECORD *)pExc->ExceptionRecord;
|
|
||||||
const CONTEXT *const pContext = (const CONTEXT *)pExc->ContextRecord;
|
|
||||||
int i, tos;
|
|
||||||
|
|
||||||
Report(hwnd, hFile, "EAX = %08lx", pContext->Eax);
|
|
||||||
Report(hwnd, hFile, "EBX = %08lx", pContext->Ebx);
|
|
||||||
Report(hwnd, hFile, "ECX = %08lx", pContext->Ecx);
|
|
||||||
Report(hwnd, hFile, "EDX = %08lx", pContext->Edx);
|
|
||||||
Report(hwnd, hFile, "EBP = %08lx", pContext->Ebp);
|
|
||||||
Report(hwnd, hFile, "DS:ESI = %04x:%08lx", pContext->SegDs, pContext->Esi);
|
|
||||||
Report(hwnd, hFile, "ES:EDI = %04x:%08lx", pContext->SegEs, pContext->Edi);
|
|
||||||
Report(hwnd, hFile, "SS:ESP = %04x:%08lx", pContext->SegSs, pContext->Esp);
|
|
||||||
Report(hwnd, hFile, "CS:EIP = %04x:%08lx", pContext->SegCs, pContext->Eip);
|
|
||||||
Report(hwnd, hFile, "FS = %04x", pContext->SegFs);
|
|
||||||
Report(hwnd, hFile, "GS = %04x", pContext->SegGs);
|
|
||||||
Report(hwnd, hFile, "EFLAGS = %08lx", pContext->EFlags);
|
|
||||||
Report(hwnd, hFile, "");
|
|
||||||
|
|
||||||
// extract out MMX registers
|
|
||||||
|
|
||||||
tos = (pContext->FloatSave.StatusWord & 0x3800)>>11;
|
|
||||||
|
|
||||||
for(i=0; i<8; i++) {
|
|
||||||
long *pReg = (long *)(pContext->FloatSave.RegisterArea + 10*((i-tos) & 7));
|
|
||||||
|
|
||||||
Report(hwnd, hFile, "MM%c = %08lx%08lx", i+'0', pReg[1], pReg[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ReportReason(HWND hwnd, HWND hwndReason, HANDLE hFile, const EXCEPTION_POINTERS *const pExc)
|
static void ReportReason(HWND hwnd, HWND hwndReason, HANDLE hFile, const EXCEPTION_POINTERS *const pExc)
|
||||||
{
|
{
|
||||||
const EXCEPTION_RECORD *const pRecord = (const EXCEPTION_RECORD *)pExc->ExceptionRecord;
|
const EXCEPTION_RECORD *const pRecord = (const EXCEPTION_RECORD *)pExc->ExceptionRecord;
|
||||||
@@ -524,33 +377,6 @@ static void ReportReason(HWND hwnd, HWND hwndReason, HANDLE hFile, const EXCEPTI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ReportThreadStacks(HWND hwnd, HANDLE hFile, const EXCEPTION_POINTERS *const pExc)
|
|
||||||
{
|
|
||||||
const char *buf = GetCheckpointLogs("\r\n");
|
|
||||||
Report( hwnd, hFile, "%s", buf );
|
|
||||||
/*
|
|
||||||
EnterCriticalSection(&g_csPerThreadState);
|
|
||||||
|
|
||||||
try {
|
|
||||||
for(List2<VirtualDubThreadStateNode>::fwit it = g_listPerThreadState.begin(); it; ++it) {
|
|
||||||
const VirtualDubThreadState *pState = it->pState;
|
|
||||||
|
|
||||||
Report(hwnd, hFile, "Thread %08lx (%s)", pState->dwThreadId, pState->pszThreadName?pState->pszThreadName:"unknown");
|
|
||||||
|
|
||||||
for(int i=0; i<CHECKPOINT_COUNT; ++i) {
|
|
||||||
const VirtualDubCheckpoint& cp = pState->cp[(pState->nNextCP+i) & (CHECKPOINT_COUNT-1)];
|
|
||||||
|
|
||||||
if (cp.file)
|
|
||||||
Report(hwnd, hFile, "\t%s:%d %s", cp.file, cp.line, cp.message? cp.message:"");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch(...) {
|
|
||||||
}
|
|
||||||
|
|
||||||
LeaveCriticalSection(&g_csPerThreadState);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *GetNameFromHeap(const char *heap, int idx) {
|
static const char *GetNameFromHeap(const char *heap, int idx) {
|
||||||
while(idx--)
|
while(idx--)
|
||||||
while(*heap++);
|
while(*heap++);
|
||||||
@@ -1102,7 +928,8 @@ void VDDebugInfoDeinit(VDDebugInfoContext *pctx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VDDebugInfoInitFromFile(VDDebugInfoContext *pctx, const char *pszFilename) {
|
bool VDDebugInfoInitFromFile(VDDebugInfoContext *pctx, const char *pszFilename)
|
||||||
|
{
|
||||||
pctx->pRawBlock = NULL;
|
pctx->pRawBlock = NULL;
|
||||||
pctx->pRVAHeap = NULL;
|
pctx->pRVAHeap = NULL;
|
||||||
|
|
||||||
@@ -1219,7 +1046,7 @@ long VDDebugInfoLookupRVA(VDDebugInfoContext *pctx, unsigned rva, char *buf, int
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static bool ReportCrashCallStack(HWND hwnd, HANDLE hFile, const EXCEPTION_POINTERS *const pExc, const void *pDebugSrc)
|
static bool ReportCrashCallStack(HWND hwnd, HANDLE hFile, const EXCEPTION_POINTERS *const pExc)
|
||||||
{
|
{
|
||||||
const CONTEXT *const pContext = (const CONTEXT *)pExc->ContextRecord;
|
const CONTEXT *const pContext = (const CONTEXT *)pExc->ContextRecord;
|
||||||
HANDLE hprMe = GetCurrentProcess();
|
HANDLE hprMe = GetCurrentProcess();
|
||||||
@@ -1266,7 +1093,7 @@ static bool ReportCrashCallStack(HWND hwnd, HANDLE hFile, const EXCEPTION_POINTE
|
|||||||
VirtualQuery((void *)data, &meminfo, sizeof meminfo);
|
VirtualQuery((void *)data, &meminfo, sizeof meminfo);
|
||||||
|
|
||||||
if (!IsExecutableProtection(meminfo.Protect) || meminfo.State!=MEM_COMMIT) {
|
if (!IsExecutableProtection(meminfo.Protect) || meminfo.State!=MEM_COMMIT) {
|
||||||
// Report(hwnd, hFile, "Rejected: %08lx (%08lx)", data, meminfo.Protect);
|
// Report(NULL, hFile, "Rejected: %08lx (%08lx)", data, meminfo.Protect);
|
||||||
fValid = false;
|
fValid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1339,28 +1166,13 @@ static bool ReportCrashCallStack(HWND hwnd, HANDLE hFile, const EXCEPTION_POINTE
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void DoSave(const EXCEPTION_POINTERS *pExc)
|
||||||
static void ReportDisasm(HWND hwnd, HANDLE hFile, const EXCEPTION_POINTERS *const pExc)
|
|
||||||
{
|
{
|
||||||
char tbuf[2048];
|
|
||||||
long idx = 0;
|
|
||||||
|
|
||||||
Report(hwnd, hFile, "Disassembly:");
|
|
||||||
|
|
||||||
while(idx = g_pcdw->getInstruction(tbuf, idx)) {
|
|
||||||
Report(hwnd, hFile, "%s", tbuf);
|
|
||||||
}
|
|
||||||
FlushFileBuffers(hFile);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
static void DoSave(const EXCEPTION_POINTERS *pExc) {
|
|
||||||
HANDLE hFile;
|
|
||||||
char szModName2[MAX_PATH];
|
char szModName2[MAX_PATH];
|
||||||
|
|
||||||
SpliceProgramPath(szModName2, sizeof szModName2, "crashinfo.txt");
|
SpliceProgramPath(szModName2, sizeof szModName2, "crashinfo.txt");
|
||||||
|
|
||||||
hFile = CreateFile(szModName2, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
HANDLE hFile = CreateFile(szModName2, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
|
||||||
if (INVALID_HANDLE_VALUE == hFile)
|
if (INVALID_HANDLE_VALUE == hFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1369,39 +1181,29 @@ static void DoSave(const EXCEPTION_POINTERS *pExc) {
|
|||||||
"--------------------------------------"
|
"--------------------------------------"
|
||||||
"\r\n", PRODUCT_NAME_VER, version_num);
|
"\r\n", PRODUCT_NAME_VER, version_num);
|
||||||
|
|
||||||
// Detect operating system.
|
|
||||||
|
|
||||||
OSVERSIONINFO ovi;
|
|
||||||
ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
||||||
|
|
||||||
ReportReason(NULL, NULL, hFile, pExc);
|
ReportReason(NULL, NULL, hFile, pExc);
|
||||||
Report(NULL, hFile, "");
|
Report(NULL, hFile, "");
|
||||||
|
|
||||||
// Dump thread stacks
|
// Dump thread stacks
|
||||||
ReportThreadStacks(NULL, hFile, pExc);
|
const char *checkpoints = GetCheckpointLogs("\r\n");
|
||||||
|
Report(NULL, hFile, "%s", checkpoints );
|
||||||
Report(NULL, hFile, "");
|
Report(NULL, hFile, "");
|
||||||
|
|
||||||
ReportCrashCallStack(NULL, hFile, pExc, g_pcdw->vdc.pExtraData);
|
ReportCrashCallStack(NULL, hFile, pExc);
|
||||||
Report(NULL, hFile, "");
|
Report(NULL, hFile, "");
|
||||||
|
|
||||||
ReportStaticLog(NULL, hFile);
|
Report(NULL, hFile, "Static log:");
|
||||||
ReportAdditionalLog(NULL, hFile);
|
Report(NULL, hFile, "%s", RageLog::GetInfo());
|
||||||
|
|
||||||
|
Report(NULL, hFile, "%s", RageLog::GetAdditionalLog() );
|
||||||
Report(NULL, hFile, "");
|
Report(NULL, hFile, "");
|
||||||
|
|
||||||
ReportCrashLog(NULL, hFile);
|
Report(NULL, hFile, "Partial log:");
|
||||||
|
int i = 0;
|
||||||
|
while( const char *p = RageLog::GetRecentLog( i++ ) )
|
||||||
|
Report(NULL, hFile, "%s", p);
|
||||||
Report(NULL, hFile, "");
|
Report(NULL, hFile, "");
|
||||||
|
|
||||||
/* We can do without these for now. People keep saying "here's a bug,
|
|
||||||
* tell me if you want the crash dump" which wastes time (of course we
|
|
||||||
* do!). Let's make the dump smaller to encourage just sending it, which
|
|
||||||
* is what people should be doing. (If we can use the SF BTS more
|
|
||||||
* consistently, instead of forums, this will be less of an issue.) */
|
|
||||||
/* ReportDisasm(NULL, hFile, pExc);
|
|
||||||
Report(NULL, hFile, "");
|
|
||||||
|
|
||||||
ReportCrashData(NULL, hFile, pExc);
|
|
||||||
Report(NULL, hFile, "");
|
|
||||||
*/
|
|
||||||
Report(NULL, hFile, "-- End of report");
|
Report(NULL, hFile, "-- End of report");
|
||||||
CloseHandle(hFile);
|
CloseHandle(hFile);
|
||||||
}
|
}
|
||||||
@@ -1441,22 +1243,17 @@ BOOL APIENTRY CrashDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
|
|||||||
|
|
||||||
case WM_INITDIALOG:
|
case WM_INITDIALOG:
|
||||||
{
|
{
|
||||||
HWND hwndList1 = GetDlgItem(hDlg, IDC_ASMBOX);
|
HWND hwndList = GetDlgItem(hDlg, IDC_CALL_STACK);
|
||||||
HWND hwndList2 = GetDlgItem(hDlg, IDC_REGDUMP);
|
|
||||||
HWND hwndList3 = GetDlgItem(hDlg, IDC_CALL_STACK);
|
|
||||||
HWND hwndReason = GetDlgItem(hDlg, IDC_STATIC_BOMBREASON);
|
HWND hwndReason = GetDlgItem(hDlg, IDC_STATIC_BOMBREASON);
|
||||||
const EXCEPTION_POINTERS *const pExc = (const EXCEPTION_POINTERS *)lParam;
|
const EXCEPTION_POINTERS *const pExc = (const EXCEPTION_POINTERS *)lParam;
|
||||||
|
|
||||||
s_pExc = pExc;
|
s_pExc = pExc;
|
||||||
|
|
||||||
g_pcdw->DoInitListbox(hwndList1);
|
if (hFontMono)
|
||||||
|
SendMessage(hwndList, WM_SETFONT, (WPARAM)hFontMono, MAKELPARAM(TRUE, 0));
|
||||||
SendMessage(hwndList2, WM_SETFONT, SendMessage(hwndList1, WM_GETFONT, 0, 0), MAKELPARAM(TRUE, 0));
|
|
||||||
SendMessage(hwndList3, WM_SETFONT, SendMessage(hwndList1, WM_GETFONT, 0, 0), MAKELPARAM(TRUE, 0));
|
|
||||||
|
|
||||||
ReportReason(NULL, hwndReason, NULL, pExc);
|
ReportReason(NULL, hwndReason, NULL, pExc);
|
||||||
ReportCrashData(hwndList2, NULL, NULL, pExc);
|
s_bHaveCallstack = ReportCrashCallStack(hwndList, NULL, pExc);
|
||||||
s_bHaveCallstack = ReportCrashCallStack(hwndList3, NULL, pExc, g_pcdw->vdc.pExtraData);
|
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
@@ -1515,12 +1312,6 @@ BOOL APIENTRY CrashDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_MEASUREITEM:
|
|
||||||
return g_pcdw->DoMeasureItem(lParam);
|
|
||||||
|
|
||||||
case WM_DRAWITEM:
|
|
||||||
return g_pcdw->DoDrawItem(lParam);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -1535,30 +1326,3 @@ void crash() {
|
|||||||
} __except(CrashHandler((EXCEPTION_POINTERS*)_exception_info())) {
|
} __except(CrashHandler((EXCEPTION_POINTERS*)_exception_info())) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ReportCrashLog(HWND hwnd, HANDLE hFile)
|
|
||||||
{
|
|
||||||
Report(NULL, hFile, "Partial log:");
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
while( const char *p = RageLog::GetRecentLog( i++ ) )
|
|
||||||
Report(hwnd, hFile, "%s", p);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ReportStaticLog(HWND hwnd, HANDLE hFile)
|
|
||||||
{
|
|
||||||
Report(NULL, hFile, "Static log:");
|
|
||||||
|
|
||||||
const char *p = RageLog::GetInfo();
|
|
||||||
DWORD dwActual;
|
|
||||||
WriteFile(hFile, p, strlen(p), &dwActual, NULL);
|
|
||||||
// Report(hwnd, hFile, "%s", staticlog);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ReportAdditionalLog(HWND hwnd, HANDLE hFile)
|
|
||||||
{
|
|
||||||
const char *p = RageLog::GetAdditionalLog();
|
|
||||||
|
|
||||||
DWORD dwActual;
|
|
||||||
WriteFile(hFile, p, strlen(p), &dwActual, NULL);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -24,30 +24,16 @@
|
|||||||
#define EXTERN extern
|
#define EXTERN extern
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct VirtualDubCheckpoint {
|
|
||||||
const char *file;
|
|
||||||
int line;
|
|
||||||
const char *message;
|
|
||||||
|
|
||||||
inline void set(const char *f, int l, const char *m=NULL) { file=f; line=l; message=m; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CHECKPOINT_COUNT (2)
|
#define CHECKPOINT_COUNT (2)
|
||||||
|
|
||||||
struct VirtualDubThreadState {
|
struct VirtualDubThreadState {
|
||||||
const char *pszThreadName;
|
const char *pszThreadName;
|
||||||
unsigned long dwThreadId;
|
unsigned long dwThreadId;
|
||||||
void * hThread;
|
void * hThread;
|
||||||
|
|
||||||
VirtualDubCheckpoint cp[CHECKPOINT_COUNT];
|
|
||||||
int nNextCP;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
EXTERN __declspec(thread) VirtualDubThreadState g_PerThreadState;
|
EXTERN __declspec(thread) VirtualDubThreadState g_PerThreadState;
|
||||||
|
|
||||||
#define VDCHECKPOINT (g_PerThreadState.cp[g_PerThreadState.nNextCP++&(CHECKPOINT_COUNT-1)].set(__FILE__, __LINE__))
|
|
||||||
#define VDCHECKPOINT_M(m) (g_PerThreadState.cp[g_PerThreadState.nNextCP++&(CHECKPOINT_COUNT-1)].set(__FILE__, __LINE__, (m)))
|
|
||||||
|
|
||||||
void VirtualDubInitializeThread(const char *pszName);
|
void VirtualDubInitializeThread(const char *pszName);
|
||||||
void VirtualDubDeinitializeThread();
|
void VirtualDubDeinitializeThread();
|
||||||
extern long __stdcall CrashHandler(struct _EXCEPTION_POINTERS *ExceptionInfo);
|
extern long __stdcall CrashHandler(struct _EXCEPTION_POINTERS *ExceptionInfo);
|
||||||
|
|||||||
Reference in New Issue
Block a user