add exception manager

This commit is contained in:
RadWolfie 2020-05-29 20:55:47 -05:00
parent d3544f7b5f
commit 64f69f78ae
2 changed files with 56 additions and 0 deletions

View File

@ -384,6 +384,46 @@ int ExitException(LPEXCEPTION_POINTERS e)
return EXCEPTION_CONTINUE_SEARCH;
}
// Exception Mananger class; Any custom exceptions must be above this line.
ExceptionManager *g_ExceptionManager = nullptr;
ExceptionManager::ExceptionManager()
{
accept_request = true;
}
ExceptionManager::~ExceptionManager()
{
for (auto i_handle : veh_handles) {
RemoveVectoredExceptionHandler(i_handle);
}
veh_handles.clear();
}
// Require to be set right before we call xbe's entry point.
void ExceptionManager::EmuX86_Init()
{
accept_request = false; // Do not allow add VEH during emulation.
}
bool ExceptionManager::AddVEH(unsigned long first, PVECTORED_EXCEPTION_HANDLER veh_handler)
{
return AddVEH(first, veh_handler, false);
}
bool ExceptionManager::AddVEH(unsigned long first, PVECTORED_EXCEPTION_HANDLER veh_handler, bool override_request)
{
bool isSuccess = false;
if (accept_request || override_request) {
void* veh_handle = AddVectoredExceptionHandler(first, veh_handler);
if (veh_handle) {
veh_handles.push_back(veh_handle);
isSuccess = true;
}
}
return isSuccess;
}
#ifdef _DEBUG
// print call stack trace
void EmuPrintStackTrace(PCONTEXT ContextRecord)

View File

@ -37,6 +37,22 @@ std::string FormatTitleId(uint32_t title_id);
// exception handler
extern LONG NTAPI lleException(EXCEPTION_POINTERS *e);
int EmuException(EXCEPTION_POINTERS *e);
class ExceptionManager {
public:
ExceptionManager();
virtual ~ExceptionManager();
// We want to make sure the core's exception is trigger front and last of exception management. For two reasons:
// Performance wise for LLE emulation and general emulation, to remove false positive exception from drivers, before we show an actual fatal error message.
void EmuX86_Init();
// If any custom VEH should be add here than try on their own. See private AddVEH function's comment.
bool AddVEH(unsigned long first, PVECTORED_EXCEPTION_HANDLER veh_handler);
private:
std::vector<void*> veh_handles;
bool accept_request;
// Since Vectored Exception Handlers are global than per thread, we only need to register once.
bool AddVEH(unsigned long first, PVECTORED_EXCEPTION_HANDLER veh_handler, bool override_request);
};
extern class ExceptionManager* g_ExceptionManager;
// print call stack trace
#ifdef _DEBUG