8 changed files with 0 additions and 550 deletions
@ -1,302 +0,0 @@
|
||||
#include "diablo.h" |
||||
|
||||
DEVILUTION_BEGIN_NAMESPACE |
||||
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter; |
||||
|
||||
int fault_unused; |
||||
|
||||
#ifndef _MSC_VER |
||||
__attribute__((constructor)) |
||||
#endif |
||||
static void |
||||
fault_c_init(void) |
||||
{ |
||||
fault_init_filter(); |
||||
fault_cleanup_filter_atexit(); |
||||
} |
||||
|
||||
SEG_ALLOCATE(SEGMENT_C_INIT) |
||||
_PVFV exception_c_init_funcs[] = { &fault_c_init }; |
||||
|
||||
void fault_init_filter() |
||||
{ |
||||
fault_set_filter(&fault_unused); |
||||
} |
||||
|
||||
void fault_cleanup_filter_atexit() |
||||
{ |
||||
atexit((void(__cdecl *)(void))fault_cleanup_filter); |
||||
} |
||||
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER __cdecl fault_cleanup_filter() |
||||
{ |
||||
return fault_reset_filter(&fault_unused); |
||||
} |
||||
|
||||
LONG __stdcall TopLevelExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo) |
||||
{ |
||||
PEXCEPTION_RECORD xcpt; |
||||
char szExceptionNameBuf[MAX_PATH]; |
||||
char szModuleName[MAX_PATH]; |
||||
char *pszExceptionName; |
||||
int sectionNumber, sectionOffset; |
||||
PCONTEXT ctx; |
||||
|
||||
log_dump_computer_info(); |
||||
xcpt = ExceptionInfo->ExceptionRecord; |
||||
pszExceptionName = fault_get_error_type(ExceptionInfo->ExceptionRecord->ExceptionCode, szExceptionNameBuf, sizeof(szExceptionNameBuf)); |
||||
log_printf("Exception code: %08X %s\r\n", xcpt->ExceptionCode, pszExceptionName); |
||||
|
||||
fault_unknown_module(xcpt->ExceptionAddress, szModuleName, MAX_PATH, §ionNumber, §ionOffset); |
||||
log_printf("Fault address:\t%08X %02X:%08X %s\r\n", xcpt->ExceptionAddress, sectionNumber, sectionOffset, szModuleName); |
||||
|
||||
ctx = ExceptionInfo->ContextRecord; |
||||
|
||||
log_printf("\r\nRegisters:\r\n"); |
||||
log_printf( |
||||
"EAX:%08X\r\nEBX:%08X\r\nECX:%08X\r\nEDX:%08X\r\nESI:%08X\r\nEDI:%08X\r\n", |
||||
ctx->Eax, |
||||
ctx->Ebx, |
||||
ctx->Ecx, |
||||
ctx->Edx, |
||||
ctx->Esi, |
||||
ctx->Edi); |
||||
log_printf("CS:EIP:%04X:%08X\r\n", ctx->SegCs, ctx->Eip); |
||||
log_printf("SS:ESP:%04X:%08X EBP:%08X\r\n", ctx->SegSs, ctx->Esp, ctx->Ebp); |
||||
log_printf("DS:%04X ES:%04X FS:%04X GS:%04X\r\n", ctx->SegDs, ctx->SegEs, ctx->SegFs, ctx->SegGs); |
||||
|
||||
log_printf("Flags:%08X\r\n", ctx->EFlags); |
||||
fault_call_stack((void *)ctx->Eip, (STACK_FRAME *)ctx->Ebp); |
||||
|
||||
log_printf("Stack bytes:\r\n"); |
||||
fault_hex_format((BYTE *)ctx->Esp, 768); |
||||
|
||||
log_printf("Code bytes:\r\n"); |
||||
fault_hex_format((BYTE *)ctx->Eip, 16); |
||||
|
||||
log_printf("\r\n"); |
||||
log_flush(1); |
||||
|
||||
if (lpTopLevelExceptionFilter) |
||||
return lpTopLevelExceptionFilter(ExceptionInfo); |
||||
return EXCEPTION_CONTINUE_SEARCH; |
||||
} |
||||
|
||||
void fault_hex_format(BYTE *ptr, DWORD numBytes) |
||||
{ |
||||
DWORD i, bytesRead; |
||||
const char *fmt; |
||||
BYTE c; |
||||
|
||||
while (numBytes > 0) { |
||||
if (numBytes < 16) |
||||
bytesRead = numBytes; |
||||
else |
||||
bytesRead = 16; |
||||
|
||||
if (IsBadReadPtr(ptr, bytesRead)) |
||||
break; |
||||
|
||||
log_printf("0x%08x: ", ptr); |
||||
|
||||
for (i = 0; i < 16; ++i) { |
||||
fmt = "%02x "; |
||||
if (i >= bytesRead) |
||||
fmt = " "; |
||||
log_printf(fmt, ptr[i]); |
||||
if (i % 4 == 3) |
||||
log_printf(" "); |
||||
} |
||||
|
||||
for (i = 0; i < bytesRead; i++) { |
||||
if (isprint(ptr[i])) |
||||
c = ptr[i]; |
||||
else |
||||
c = '.'; |
||||
log_printf("%c", c); |
||||
} |
||||
|
||||
log_printf("\r\n"); |
||||
ptr += bytesRead; |
||||
numBytes -= bytesRead; |
||||
} |
||||
log_printf("\r\n"); |
||||
} |
||||
|
||||
void fault_unknown_module(LPCVOID lpAddress, LPSTR lpModuleName, int iMaxLength, int *sectionNum, int *sectionOffset) |
||||
{ |
||||
MEMORY_BASIC_INFORMATION memInfo; |
||||
PIMAGE_DOS_HEADER dosHeader; |
||||
LONG ntOffset; |
||||
PIMAGE_NT_HEADERS ntHeader; |
||||
PIMAGE_SECTION_HEADER section; |
||||
DWORD numSections, moduleOffset, sectionSize, sectionAddress; |
||||
int i; |
||||
|
||||
lstrcpyn(lpModuleName, "*unknown*", iMaxLength); |
||||
*sectionNum = 0; |
||||
*sectionOffset = 0; |
||||
|
||||
if (!VirtualQuery(lpAddress, &memInfo, sizeof(memInfo))) |
||||
return; |
||||
|
||||
dosHeader = (PIMAGE_DOS_HEADER)memInfo.AllocationBase; |
||||
if (!memInfo.AllocationBase) |
||||
dosHeader = (PIMAGE_DOS_HEADER)GetModuleHandle(0); |
||||
|
||||
if (!GetModuleFileName((HMODULE)dosHeader, lpModuleName, iMaxLength)) { |
||||
lstrcpyn(lpModuleName, "*unknown*", iMaxLength); |
||||
return; |
||||
} |
||||
|
||||
if (dosHeader && dosHeader->e_magic == IMAGE_DOS_SIGNATURE) { |
||||
ntOffset = dosHeader->e_lfanew; |
||||
if (ntOffset) { |
||||
ntHeader = (PIMAGE_NT_HEADERS)((DWORD)dosHeader + ntOffset); |
||||
if (ntHeader->Signature == IMAGE_NT_SIGNATURE) { |
||||
section = IMAGE_FIRST_SECTION(ntHeader); |
||||
numSections = ntHeader->FileHeader.NumberOfSections; |
||||
moduleOffset = (BYTE *)lpAddress - (BYTE *)dosHeader; |
||||
for (i = 0; i < numSections; i++, section++) { |
||||
sectionSize = section->SizeOfRawData; |
||||
sectionAddress = section->VirtualAddress; |
||||
if (section->SizeOfRawData <= section->Misc.VirtualSize) |
||||
sectionSize = section->Misc.VirtualSize; |
||||
|
||||
if (moduleOffset >= sectionAddress && moduleOffset <= sectionAddress + sectionSize) { |
||||
*sectionNum = i + 1; |
||||
*sectionOffset = moduleOffset - sectionAddress; |
||||
return; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
void fault_call_stack(void *instr, STACK_FRAME *stackFrame) |
||||
{ |
||||
STACK_FRAME *oldStackFrame; |
||||
char szModuleName[MAX_PATH]; |
||||
int sectionNumber, sectionOffset; |
||||
|
||||
log_printf("Call stack:\r\nAddress Frame Logical addr Module\r\n"); |
||||
do { |
||||
fault_unknown_module(instr, szModuleName, MAX_PATH, §ionNumber, §ionOffset); |
||||
log_printf("%08X %08X %04X:%08X %s\r\n", instr, stackFrame, sectionNumber, sectionOffset, szModuleName); |
||||
|
||||
if (IsBadWritePtr(stackFrame, 8)) |
||||
break; |
||||
|
||||
instr = stackFrame->pCallRet; |
||||
oldStackFrame = stackFrame; |
||||
stackFrame = stackFrame->pNext; |
||||
|
||||
if ((DWORD)stackFrame % 4 != 0) |
||||
break; |
||||
} while (stackFrame > oldStackFrame && !IsBadWritePtr(stackFrame, 8)); |
||||
|
||||
log_printf("\r\n"); |
||||
} |
||||
|
||||
char *fault_get_error_type(DWORD dwMessageId, LPSTR lpString1, DWORD nSize) |
||||
{ |
||||
const char *s; |
||||
|
||||
switch (dwMessageId) { |
||||
case EXCEPTION_STACK_OVERFLOW: |
||||
s = "STACK_OVERFLOW"; |
||||
break; |
||||
case EXCEPTION_FLT_DIVIDE_BY_ZERO: |
||||
s = "FLT_DIVIDE_BY_ZERO"; |
||||
break; |
||||
case EXCEPTION_FLT_INEXACT_RESULT: |
||||
s = "FLT_INEXACT_RESULT"; |
||||
break; |
||||
case EXCEPTION_FLT_INVALID_OPERATION: |
||||
s = "FLT_INVALID_OPERATION"; |
||||
break; |
||||
case EXCEPTION_FLT_OVERFLOW: |
||||
s = "FLT_OVERFLOW"; |
||||
break; |
||||
case EXCEPTION_FLT_STACK_CHECK: |
||||
s = "FLT_STACK_CHECK"; |
||||
break; |
||||
case EXCEPTION_FLT_UNDERFLOW: |
||||
s = "FLT_UNDERFLOW"; |
||||
break; |
||||
case EXCEPTION_INT_DIVIDE_BY_ZERO: |
||||
s = "INT_DIVIDE_BY_ZERO"; |
||||
break; |
||||
case EXCEPTION_INT_OVERFLOW: |
||||
s = "INT_OVERFLOW"; |
||||
break; |
||||
case EXCEPTION_PRIV_INSTRUCTION: |
||||
s = "PRIV_INSTRUCTION"; |
||||
break; |
||||
case EXCEPTION_FLT_DENORMAL_OPERAND: |
||||
s = "FLT_DENORMAL_OPERAND"; |
||||
break; |
||||
case EXCEPTION_INVALID_HANDLE: |
||||
s = "INVALID_HANDLE"; |
||||
break; |
||||
case EXCEPTION_ILLEGAL_INSTRUCTION: |
||||
s = "ILLEGAL_INSTRUCTION"; |
||||
break; |
||||
case EXCEPTION_NONCONTINUABLE_EXCEPTION: |
||||
s = "NONCONTINUABLE_EXCEPTION"; |
||||
break; |
||||
case EXCEPTION_INVALID_DISPOSITION: |
||||
s = "INVALID_DISPOSITION"; |
||||
break; |
||||
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: |
||||
s = "ARRAY_BOUNDS_EXCEEDED"; |
||||
break; |
||||
case EXCEPTION_IN_PAGE_ERROR: |
||||
s = "IN_PAGE_ERROR"; |
||||
break; |
||||
case EXCEPTION_GUARD_PAGE: |
||||
s = "GUARD_PAGE"; |
||||
break; |
||||
case EXCEPTION_DATATYPE_MISALIGNMENT: |
||||
s = "DATATYPE_MISALIGNMENT"; |
||||
break; |
||||
case EXCEPTION_BREAKPOINT: |
||||
s = "BREAKPOINT"; |
||||
break; |
||||
case EXCEPTION_SINGLE_STEP: |
||||
s = "SINGLE_STEP"; |
||||
break; |
||||
case EXCEPTION_ACCESS_VIOLATION: |
||||
s = "ACCESS_VIOLATION"; |
||||
break; |
||||
default: |
||||
if (FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, (LPCVOID)GetModuleHandle("NTDLL.DLL"), dwMessageId, 0, lpString1, nSize, NULL)) { |
||||
return lpString1; |
||||
} |
||||
s = "*unknown*"; |
||||
break; |
||||
} |
||||
lstrcpyn(lpString1, s, nSize); |
||||
return lpString1; |
||||
} |
||||
|
||||
void *fault_set_filter(void *unused) |
||||
{ |
||||
lpTopLevelExceptionFilter = SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)TopLevelExceptionFilter); |
||||
return unused; |
||||
} |
||||
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER fault_reset_filter(void *unused) |
||||
{ |
||||
//return SetUnhandledExceptionFilter(lpTopLevelExceptionFilter);
|
||||
return lpTopLevelExceptionFilter; |
||||
} |
||||
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER fault_get_filter() |
||||
{ |
||||
return lpTopLevelExceptionFilter; |
||||
} |
||||
|
||||
DEVILUTION_END_NAMESPACE |
||||
@ -1,25 +0,0 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __FAULT_H__ |
||||
#define __FAULT_H__ |
||||
|
||||
typedef struct STACK_FRAME { |
||||
struct STACK_FRAME *pNext; |
||||
void *pCallRet; |
||||
} STACK_FRAME; |
||||
|
||||
extern int fault_unused; |
||||
extern LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter; |
||||
|
||||
void fault_init_filter(); |
||||
void fault_cleanup_filter_atexit(); |
||||
LPTOP_LEVEL_EXCEPTION_FILTER __cdecl fault_cleanup_filter(); |
||||
LONG __stdcall TopLevelExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo); |
||||
void fault_hex_format(BYTE *ptr, DWORD numBytes); |
||||
void fault_unknown_module(LPCVOID lpAddress, LPSTR lpModuleName, int iMaxLength, int *sectionNum, int *sectionOffset); |
||||
void fault_call_stack(void *instr, STACK_FRAME *stackAddr); |
||||
char *fault_get_error_type(DWORD dwMessageId, LPSTR lpString1, DWORD nSize); |
||||
void *fault_set_filter(void *unused); |
||||
LPTOP_LEVEL_EXCEPTION_FILTER fault_reset_filter(void *unused); |
||||
LPTOP_LEVEL_EXCEPTION_FILTER fault_get_filter(); |
||||
|
||||
#endif /* __FAULT_H__ */ |
||||
@ -1,181 +0,0 @@
|
||||
#include "diablo.h" |
||||
#include "../3rdParty/Storm/Source/storm.h" |
||||
|
||||
DEVILUTION_BEGIN_NAMESPACE |
||||
|
||||
static CCritSect sgMemCrit; |
||||
CHAR FileName[MAX_PATH]; |
||||
char log_buffer[388]; |
||||
LPCVOID lpAddress; |
||||
DWORD nNumberOfBytesToWrite; |
||||
|
||||
/* data */ |
||||
|
||||
BOOL log_not_created = 1; |
||||
HANDLE log_file = INVALID_HANDLE_VALUE; |
||||
|
||||
void __cdecl log_flush(BOOL force_close) |
||||
{ |
||||
DWORD NumberOfBytesWritten; |
||||
|
||||
sgMemCrit.Enter(); |
||||
if (nNumberOfBytesToWrite) { |
||||
if (log_file == INVALID_HANDLE_VALUE) { |
||||
log_file = log_create(); |
||||
if (log_file == INVALID_HANDLE_VALUE) { |
||||
nNumberOfBytesToWrite = 0; |
||||
return; |
||||
} |
||||
SetFilePointer(log_file, 0, NULL, FILE_END); |
||||
} |
||||
WriteFile(log_file, lpAddress, nNumberOfBytesToWrite, &NumberOfBytesWritten, 0); |
||||
nNumberOfBytesToWrite = 0; |
||||
} |
||||
if (force_close && log_file != INVALID_HANDLE_VALUE) { |
||||
CloseHandle(log_file); |
||||
log_file = INVALID_HANDLE_VALUE; |
||||
} |
||||
sgMemCrit.Leave(); |
||||
} |
||||
|
||||
HANDLE log_create() |
||||
{ |
||||
char *last_slash_pos; |
||||
HANDLE fh; |
||||
VS_FIXEDFILEINFO file_info; |
||||
DWORD i; |
||||
char buf[32]; |
||||
|
||||
if (log_not_created) { |
||||
char filename_tmp[MAX_PATH]; |
||||
if (GetModuleFileName(NULL, filename_tmp, sizeof filename_tmp) == 0) |
||||
filename_tmp[0] = '\0'; |
||||
else { |
||||
last_slash_pos = strrchr(filename_tmp, '\\'); |
||||
if (last_slash_pos == NULL) |
||||
filename_tmp[0] = '\0'; |
||||
else |
||||
*(last_slash_pos + 1) = '\0'; |
||||
} |
||||
i = 32; |
||||
if (!GetUserName(buf, &i)) |
||||
buf[0] = '\0'; |
||||
log_get_version(&file_info); |
||||
_snprintf( |
||||
FileName, |
||||
sizeof(filename_tmp), |
||||
"%s%s%02u%02u%02u.ERR", |
||||
filename_tmp, |
||||
buf, |
||||
file_info.dwProductVersionMS & 0xFFFF, |
||||
file_info.dwProductVersionLS >> 16, |
||||
file_info.dwProductVersionLS & 0xFFFF); |
||||
} |
||||
fh = INVALID_HANDLE_VALUE; |
||||
for (i = log_not_created ? 0 : 1; (int)i < 2; i++) { |
||||
fh = CreateFile(FileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); |
||||
if (fh != INVALID_HANDLE_VALUE) { |
||||
if (GetFileSize(fh, NULL) > 0x10000) |
||||
SetEndOfFile(fh); |
||||
break; |
||||
} |
||||
last_slash_pos = strrchr(FileName, '\\'); |
||||
if (!last_slash_pos) |
||||
last_slash_pos = FileName; |
||||
char filename_tmp[MAX_PATH] = "c:\\"; |
||||
strcat(filename_tmp, last_slash_pos); |
||||
strcpy(FileName, filename_tmp); |
||||
} |
||||
log_not_created = FALSE; |
||||
return fh; |
||||
} |
||||
|
||||
void log_get_version(VS_FIXEDFILEINFO *file_info) |
||||
{ |
||||
DWORD size, len, dwHandle; |
||||
unsigned int puLen; |
||||
void *version; |
||||
char Filename[MAX_PATH]; |
||||
LPVOID lpBuffer; |
||||
|
||||
memset(file_info, 0, sizeof(*file_info)); |
||||
if (GetModuleFileName(0, Filename, sizeof(Filename))) { |
||||
size = GetFileVersionInfoSize(Filename, &dwHandle); |
||||
if (size) { |
||||
version = VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); |
||||
if (GetFileVersionInfo(Filename, 0, size, version) && VerQueryValue(version, "\\", &lpBuffer, &puLen)) { |
||||
len = puLen; |
||||
if (puLen >= 52) |
||||
len = 52; |
||||
memcpy(file_info, lpBuffer, len); |
||||
} |
||||
VirtualFree(version, 0, MEM_RELEASE); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void __cdecl log_printf(const char *pszFmt, ...) |
||||
{ |
||||
size_t size; |
||||
char *pBuffer; |
||||
char msg[512]; |
||||
va_list va; |
||||
|
||||
sgMemCrit.Enter(); |
||||
va_start(va, pszFmt); |
||||
_vsnprintf(msg, 0x200, pszFmt, va); |
||||
va_end(va); |
||||
msg[511] = 0; |
||||
size = strlen(msg); |
||||
if (size + nNumberOfBytesToWrite > 0x1000) { |
||||
log_flush(0); |
||||
} |
||||
|
||||
if (lpAddress == NULL) { |
||||
lpAddress = (char *)VirtualAlloc((LPVOID)lpAddress, 0x1000, MEM_COMMIT, PAGE_READWRITE); |
||||
pBuffer = (char *)lpAddress; |
||||
nNumberOfBytesToWrite = 0; |
||||
} |
||||
if (lpAddress != NULL) { |
||||
pBuffer = (char *)lpAddress; |
||||
memcpy(&pBuffer[nNumberOfBytesToWrite], msg, size); |
||||
nNumberOfBytesToWrite += size; |
||||
} |
||||
sgMemCrit.Leave(); |
||||
} |
||||
|
||||
void log_dump_computer_info() |
||||
{ |
||||
char Buffer[64]; |
||||
VS_FIXEDFILEINFO file_info; |
||||
SYSTEMTIME SystemTime; |
||||
DWORD pcbBuffer; |
||||
|
||||
GetLocalTime(&SystemTime); |
||||
pcbBuffer = 64; |
||||
if (!GetUserName(Buffer, &pcbBuffer)) |
||||
Buffer[0] = 0; |
||||
log_get_version(&file_info); |
||||
log_printf( |
||||
"\r\n" |
||||
"------------------------------------------------------\r\n" |
||||
"PROGRAM VERSION: %d.%d.%d.%d\r\n" |
||||
"COMPUTER NAME: %s\r\n" |
||||
"TIME: %02u/%02u/%02u %02u:%02u:%02u\r\n" |
||||
"INFO: %s\r\n" |
||||
"\r\n", |
||||
file_info.dwProductVersionMS >> 16, |
||||
file_info.dwProductVersionMS & 0xFFFF, |
||||
file_info.dwProductVersionLS >> 16, |
||||
file_info.dwProductVersionLS & 0xFFFF, |
||||
Buffer, |
||||
SystemTime.wMonth, |
||||
SystemTime.wDay, |
||||
SystemTime.wYear % 100, |
||||
SystemTime.wHour, |
||||
SystemTime.wMinute, |
||||
SystemTime.wSecond, |
||||
log_buffer); |
||||
} |
||||
|
||||
DEVILUTION_END_NAMESPACE |
||||
@ -1,23 +0,0 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __LOGGING_H__ |
||||
#define __LOGGING_H__ |
||||
|
||||
extern CHAR FileName[MAX_PATH]; |
||||
extern char log_buffer[388]; |
||||
extern LPCVOID lpAddress; |
||||
extern DWORD nNumberOfBytesToWrite; |
||||
|
||||
void __cdecl log_flush(BOOL force_close); |
||||
HANDLE log_create(); |
||||
void log_get_version(VS_FIXEDFILEINFO *file_info); |
||||
void __cdecl log_printf(const char *pszFmt, ...); // LogMessage
|
||||
void log_dump_computer_info(); |
||||
|
||||
/* rdata */ |
||||
|
||||
/* data */ |
||||
|
||||
extern int log_not_created; |
||||
extern HANDLE log_file; |
||||
|
||||
#endif /* __LOGGING_H__ */ |
||||
Loading…
Reference in new issue