forked from 0ad/0ad
add crash log (call stack and minidump)
This was SVN commit r757.
This commit is contained in:
parent
370e328e89
commit
b284b47a06
@ -59,7 +59,6 @@ void debug_break()
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
double round(double x)
|
||||
|
@ -26,12 +26,16 @@ extern void debug_break();
|
||||
// shown in a dialog, which offers
|
||||
// continue, break, suppress (ignore this assert), and exit
|
||||
/*
|
||||
* return values:
|
||||
* 0 - continue
|
||||
* 1 - suppress
|
||||
* 2 - break
|
||||
*/
|
||||
extern int debug_assert_failed(const char* file, int line, const char* expr);
|
||||
* return values:
|
||||
* 0 - continue
|
||||
* 1 - suppress
|
||||
* 2 - break
|
||||
*/
|
||||
|
||||
extern int debug_assert_failed(const char* source_file, int line, const char* expr);
|
||||
|
||||
extern int debug_write_crashlog(const char* file);
|
||||
|
||||
|
||||
extern void check_heap();
|
||||
|
||||
|
@ -11,3 +11,5 @@ FUNC(BOOL, SymGetTypeInfo, (HANDLE, DWORD64, ULONG, IMAGEHLP_SYMBOL_TYPE_INFO, v
|
||||
FUNC(BOOL, SymFromAddr, (HANDLE, DWORD64, DWORD64*, SYMBOL_INFO*))
|
||||
FUNC(ULONG, SymSetContext, (HANDLE, IMAGEHLP_STACK_FRAME*, IMAGEHLP_CONTEXT*))
|
||||
FUNC(BOOL, SymEnumSymbols, (HANDLE, ULONG64, const char*, PSYM_ENUMERATESYMBOLS_CALLBACK, void*))
|
||||
|
||||
FUNC(BOOL, MiniDumpWriteDump, (HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION, PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION))
|
||||
|
@ -611,10 +611,15 @@ static void set_exception_handler()
|
||||
}
|
||||
|
||||
|
||||
static void init()
|
||||
{
|
||||
ONCE(dbg_init());
|
||||
}
|
||||
|
||||
|
||||
int debug_assert_failed(const char* file, int line, const char* expr)
|
||||
{
|
||||
ONCE(dbg_init());
|
||||
init();
|
||||
|
||||
int pos = swprintf(buf, 1000, L"Assertion failed in %hs, line %d: %hs\r\n", file, line, expr);
|
||||
walk_stack(2, buf+pos);
|
||||
@ -635,3 +640,59 @@ static int wdbg_init()
|
||||
#pragma data_seg(".LIB$WIB") // first
|
||||
WIN_REGISTER_FUNC(wdbg_init);
|
||||
#pragma data_seg()
|
||||
|
||||
|
||||
// from http://www.codeproject.com/debug/XCrashReportPt3.asp
|
||||
static void DumpMiniDump(HANDLE hFile, PEXCEPTION_POINTERS excpInfo)
|
||||
{
|
||||
/*
|
||||
if (excpInfo == NULL)
|
||||
{
|
||||
// Generate exception to get proper context in dump
|
||||
__try
|
||||
{
|
||||
OutputDebugString("RaiseException for MinidumpWriteDump\n");
|
||||
RaiseException(EXCEPTION_BREAKPOINT, 0, 0, NULL);
|
||||
}
|
||||
__except(DumpMiniDump(hFile, GetExceptionInformation()), EXCEPTION_CONTINUE_EXECUTION)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{*/
|
||||
MINIDUMP_EXCEPTION_INFORMATION eInfo;
|
||||
eInfo.ThreadId = GetCurrentThreadId();
|
||||
eInfo.ExceptionPointers = excpInfo;
|
||||
eInfo.ClientPointers = FALSE;
|
||||
|
||||
// note: MiniDumpWithIndirectlyReferencedMemory does not work on Win98
|
||||
_MiniDumpWriteDump(
|
||||
GetCurrentProcess(),
|
||||
GetCurrentProcessId(),
|
||||
hFile,
|
||||
MiniDumpNormal,
|
||||
excpInfo ? &eInfo : NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
// }
|
||||
}
|
||||
|
||||
int debug_write_crashlog(const char* file)
|
||||
{
|
||||
init();
|
||||
|
||||
int len = swprintf(buf, 1000, L"Undefined state reached.\r\n");
|
||||
walk_stack(2, buf+len);
|
||||
|
||||
FILE* f = fopen(file, "w");
|
||||
fwrite(buf, pos-buf, 2, f);
|
||||
fclose(f);
|
||||
|
||||
char dmp_file[MAX_PATH];
|
||||
strcpy(dmp_file, file);
|
||||
strcat(dmp_file, ".mdmp");
|
||||
HANDLE hFile = CreateFile(dmp_file, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0);
|
||||
DumpMiniDump(hFile, 0);
|
||||
|
||||
return 0;
|
||||
}
|
@ -321,8 +321,10 @@ extern u64 rdtsc();
|
||||
extern u64 PREVTSC;
|
||||
u64 PREVTSC;
|
||||
|
||||
|
||||
int entry()
|
||||
{
|
||||
|
||||
#ifdef _MSC_VER
|
||||
u64 TSC=rdtsc();
|
||||
debug_out(
|
||||
|
@ -155,14 +155,14 @@ static int write_sys_info();
|
||||
// TODO: load from language file
|
||||
// these will need to be variables; better to make an index into string table
|
||||
// (as with errors)? if it's a string, what happens if lang file load failed?
|
||||
#define STR_UNHANDLED_EXCEPTION L"unhandled exception"
|
||||
#define STR_UNHANDLED_EXCEPTION L"unhandled exception. crash log has been written; please report at bugs.wildfiregames.com"
|
||||
#define STR_SDL_INIT_FAILED L"SDL library initialization failed: %hs\n"
|
||||
#define STR_SET_VMODE_FAILED L"could not set %dx%d graphics mode: %hs\n"
|
||||
#define STR_OGL_EXT_MISSING L"required ARB_multitexture or ARB_texture_env_combine extension not available"
|
||||
#define STR_MAP_LOAD_FAILED L"Failed to load map %hs\n"
|
||||
|
||||
|
||||
static void Die(int err, const wchar_t* fmt, ...)
|
||||
void Die(int err, const wchar_t* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
@ -179,6 +179,7 @@ static void Die(int err, const wchar_t* fmt, ...)
|
||||
wdisplay_msg(L"0ad", buf);
|
||||
|
||||
write_sys_info();
|
||||
debug_write_crashlog("crashlog.txt");
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user