1
0
mirror of https://github.com/FunkyFr3sh/cnc-ddraw.git synced 2025-03-25 01:57:47 +01:00

tweak exception handler

This commit is contained in:
FunkyFr3sh 2024-09-24 23:36:11 +02:00
parent e0e59cd9fa
commit 80b8a996a7
3 changed files with 61 additions and 97 deletions

View File

@ -6,6 +6,7 @@
#include <intrin.h> #include <intrin.h>
LONG WINAPI dbg_exception_handler(EXCEPTION_POINTERS* exception); LONG WINAPI dbg_exception_handler(EXCEPTION_POINTERS* exception);
LONG WINAPI dbg_vectored_exception_handler(EXCEPTION_POINTERS* exception);
void dbg_counter_start(); void dbg_counter_start();
double dbg_counter_stop(); double dbg_counter_stop();
void dbg_debug_string(const char* format, ...); void dbg_debug_string(const char* format, ...);
@ -33,6 +34,7 @@ void __cdecl dbg_invoke_watson(wchar_t const*, wchar_t const*, wchar_t const*, u
extern double g_dbg_frame_time; extern double g_dbg_frame_time;
extern DWORD g_dbg_frame_count; extern DWORD g_dbg_frame_count;
extern LPTOP_LEVEL_EXCEPTION_FILTER g_dbg_exception_filter; extern LPTOP_LEVEL_EXCEPTION_FILTER g_dbg_exception_filter;
extern PVOID g_dbg_exception_handle;
#if defined(__GNUC__) /* wrap msvc intrinsics onto gcc builtins */ #if defined(__GNUC__) /* wrap msvc intrinsics onto gcc builtins */
#undef _ReturnAddress #undef _ReturnAddress

View File

@ -15,12 +15,12 @@
#include "utils.h" #include "utils.h"
#include "dllmain.h" #include "dllmain.h"
#include "config.h" #include "config.h"
#include "patch.h"
double g_dbg_frame_time = 0; double g_dbg_frame_time = 0;
DWORD g_dbg_frame_count = 0; DWORD g_dbg_frame_count = 0;
LPTOP_LEVEL_EXCEPTION_FILTER g_dbg_exception_filter; LPTOP_LEVEL_EXCEPTION_FILTER g_dbg_exception_filter;
PVOID g_dbg_exception_handle;
static LONGLONG g_dbg_counter_start_time = 0; static LONGLONG g_dbg_counter_start_time = 0;
static double g_dbg_counter_freq = 0.0; static double g_dbg_counter_freq = 0.0;
@ -37,98 +37,59 @@ static int g_dbg_crash_count = 0;
LONG WINAPI dbg_exception_handler(EXCEPTION_POINTERS* exception) LONG WINAPI dbg_exception_handler(EXCEPTION_POINTERS* exception)
{ {
if (!exception || !exception->ExceptionRecord) g_dbg_crash_count++;
{
if (g_dbg_exception_filter)
return g_dbg_exception_filter(exception);
return EXCEPTION_EXECUTE_HANDLER; HANDLE dmp =
CreateFile(
g_dbg_crash_count == 1 ? g_dbg_dmp_path1 : g_dbg_dmp_path2,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ,
0,
CREATE_ALWAYS,
0,
0);
if (dmp != INVALID_HANDLE_VALUE)
{
MINIDUMP_EXCEPTION_INFORMATION info;
info.ThreadId = GetCurrentThreadId();
info.ExceptionPointers = exception;
info.ClientPointers = TRUE;
MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
dmp,
0,
&info,
NULL,
NULL);
CloseHandle(dmp);
} }
if (exception->ExceptionRecord->ExceptionCode != STATUS_PRIVILEGED_INSTRUCTION || !g_config.ignore_exceptions) if (exception && exception->ExceptionRecord)
{ {
g_dbg_crash_count++; HMODULE mod = NULL;
char filename[MAX_PATH] = { 0 };
HANDLE dmp =
CreateFile(
g_dbg_crash_count == 1 ? g_dbg_dmp_path1 : g_dbg_dmp_path2,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ,
0,
CREATE_ALWAYS,
0,
0);
if (dmp != INVALID_HANDLE_VALUE)
{
MINIDUMP_EXCEPTION_INFORMATION info;
info.ThreadId = GetCurrentThreadId();
info.ExceptionPointers = exception;
info.ClientPointers = TRUE;
MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
dmp,
0,
&info,
NULL,
NULL);
CloseHandle(dmp);
}
}
HMODULE mod = NULL;
char filename[MAX_PATH] = { 0 };
#if defined(_MSC_VER) /* comment this out just to keep the mingw build win2000 compatible */ #if defined(_MSC_VER) /* comment this out just to keep the mingw build win2000 compatible */
if (GetModuleHandleExA( if (GetModuleHandleExA(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
exception->ExceptionRecord->ExceptionAddress, exception->ExceptionRecord->ExceptionAddress,
&mod)) &mod))
{ {
GetModuleFileNameA(mod, filename, sizeof(filename) - 1); GetModuleFileNameA(mod, filename, sizeof(filename) - 1);
} }
#endif #endif
TRACE( TRACE(
"Exception at %p (%p+%p), Code=%08X - %s\n", "Exception at %p (%p+%p), Code=%08X - %s\n",
exception->ExceptionRecord->ExceptionAddress, exception->ExceptionRecord->ExceptionAddress,
mod, mod,
(int)exception->ExceptionRecord->ExceptionAddress - (int)mod, (int)exception->ExceptionRecord->ExceptionAddress - (int)mod,
exception->ExceptionRecord->ExceptionCode, exception->ExceptionRecord->ExceptionCode,
filename); filename);
if (g_config.ignore_exceptions &&
exception->ContextRecord &&
exception->ExceptionRecord->ExceptionAddress &&
exception->ExceptionRecord->ExceptionCode == STATUS_PRIVILEGED_INSTRUCTION)
{
size_t size = 0;
BYTE* addr = exception->ExceptionRecord->ExceptionAddress;
switch (*addr)
{
case 0xE4: // IN ib
case 0xE5: // IN id
case 0xE6: // OUT ib
case 0xE7: // OUT ib
size = 2;
break;
case 0xEC: // IN ib
case 0xED: // IN id
case 0xEE: // OUT
case 0xEF: // OUT
size = 1;
break;
}
if (size)
{
exception->ContextRecord->Eip += size;
patch_clear((void*)addr, 0x90, (char*)addr + size);
return EXCEPTION_CONTINUE_EXECUTION;
}
} }
if (g_dbg_exception_filter) if (g_dbg_exception_filter)
@ -152,8 +113,9 @@ void __cdecl dbg_invoke_watson(
TerminateProcess(GetCurrentProcess(), STATUS_INVALID_CRUNTIME_PARAMETER); TerminateProcess(GetCurrentProcess(), STATUS_INVALID_CRUNTIME_PARAMETER);
} }
#else #endif
LONG WINAPI dbg_exception_handler(EXCEPTION_POINTERS* exception)
LONG WINAPI dbg_vectored_exception_handler(EXCEPTION_POINTERS* exception)
{ {
if (exception && if (exception &&
exception->ContextRecord && exception->ContextRecord &&
@ -182,17 +144,12 @@ LONG WINAPI dbg_exception_handler(EXCEPTION_POINTERS* exception)
if (size) if (size)
{ {
exception->ContextRecord->Eip += size; exception->ContextRecord->Eip += size;
patch_clear((void*)addr, 0x90, (char*)addr + size);
return EXCEPTION_CONTINUE_EXECUTION; return EXCEPTION_CONTINUE_EXECUTION;
} }
} }
if (g_dbg_exception_filter) return EXCEPTION_CONTINUE_SEARCH;
return g_dbg_exception_filter(exception);
return EXCEPTION_EXECUTE_HANDLER;
} }
#endif
void dbg_init() void dbg_init()
{ {

View File

@ -43,14 +43,15 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
#ifdef _DEBUG #ifdef _DEBUG
dbg_init(); dbg_init();
g_dbg_exception_filter = real_SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)dbg_exception_handler); g_dbg_exception_filter = real_SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)dbg_exception_handler);
#endif
cfg_load(); cfg_load();
#else
cfg_load();
if (g_config.ignore_exceptions) if (g_config.ignore_exceptions)
{ {
g_dbg_exception_filter = real_SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)dbg_exception_handler); g_dbg_exception_handle =
AddVectoredExceptionHandler(1, (PVECTORED_EXCEPTION_HANDLER)dbg_vectored_exception_handler);
} }
#endif
char buf[1024]; char buf[1024];
@ -147,6 +148,10 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
keyboard_hook_exit(); keyboard_hook_exit();
dinput_hook_exit(); dinput_hook_exit();
hook_exit(); hook_exit();
if (g_dbg_exception_handle)
RemoveVectoredExceptionHandler(g_dbg_exception_handle);
break; break;
} }
} }