mirror of https://github.com/x64dbg/TitanEngine
Added a fix to handle race conditions on multi-threaded applications on multi-core systems (DBG_REPLY_LATER)
This commit is contained in:
parent
8d93135f38
commit
284a782702
|
|
@ -52,6 +52,24 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
||||||
|
|
||||||
wchar_t* szTranslatedNativeName;
|
wchar_t* szTranslatedNativeName;
|
||||||
|
|
||||||
|
DWORD ThreadBeingProcessed = 0;
|
||||||
|
std::vector<THREAD_ITEM_DATA> SuspendedThreads;
|
||||||
|
bool IsDbgReplyLaterSupported = false;
|
||||||
|
|
||||||
|
// Check if DBG_REPLY_LATER is supported based on Windows version (Windows 10, version 1507 or above)
|
||||||
|
OSVERSIONINFOEXA OSInfo;
|
||||||
|
OSInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
|
||||||
|
|
||||||
|
if (GetVersionExA((LPOSVERSIONINFOA)&OSInfo))
|
||||||
|
{
|
||||||
|
if (OSInfo.wProductType == VER_NT_WORKSTATION &&
|
||||||
|
(OSInfo.dwMajorVersion > 10 ||
|
||||||
|
(OSInfo.dwMajorVersion == 10 && OSInfo.dwBuildNumber >= 1507)))
|
||||||
|
{
|
||||||
|
IsDbgReplyLaterSupported = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DBGFileHandle = NULL;
|
DBGFileHandle = NULL;
|
||||||
DBGCode = DBG_CONTINUE;
|
DBGCode = DBG_CONTINUE;
|
||||||
engineFakeDLLHandle = NULL;
|
engineFakeDLLHandle = NULL;
|
||||||
|
|
@ -97,6 +115,18 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsDbgReplyLaterSupported && DBGEvent.dwDebugEventCode == EXCEPTION_DEBUG_EVENT)
|
||||||
|
{
|
||||||
|
// Check if there is a thread processing a single step
|
||||||
|
if (ThreadBeingProcessed != 0 && DBGEvent.dwThreadId != ThreadBeingProcessed)
|
||||||
|
{
|
||||||
|
// Reply to the dbg event later
|
||||||
|
DBGCode = DBG_REPLY_LATER;
|
||||||
|
|
||||||
|
goto continue_dbg_event;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(engineExecutePluginCallBack)
|
if(engineExecutePluginCallBack)
|
||||||
{
|
{
|
||||||
ExtensionManagerPluginDebugCallBack(&DBGEvent, UE_PLUGIN_CALL_REASON_EXCEPTION);
|
ExtensionManagerPluginDebugCallBack(&DBGEvent, UE_PLUGIN_CALL_REASON_EXCEPTION);
|
||||||
|
|
@ -560,6 +590,16 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
||||||
|
|
||||||
case STATUS_SINGLE_STEP:
|
case STATUS_SINGLE_STEP:
|
||||||
{
|
{
|
||||||
|
if (IsDbgReplyLaterSupported)
|
||||||
|
{
|
||||||
|
// Resume the other threads since we are done processing the single step
|
||||||
|
for (auto& Thread : SuspendedThreads)
|
||||||
|
ResumeThread(Thread.hThread);
|
||||||
|
|
||||||
|
SuspendedThreads.clear();
|
||||||
|
ThreadBeingProcessed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(ResetBPX == true || ResetHwBPX == true || ResetMemBPX == true) //restore breakpoints (internal step)
|
if(ResetBPX == true || ResetHwBPX == true || ResetMemBPX == true) //restore breakpoints (internal step)
|
||||||
{
|
{
|
||||||
DBGCode = DBG_CONTINUE;
|
DBGCode = DBG_CONTINUE;
|
||||||
|
|
@ -1162,6 +1202,37 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsDbgReplyLaterSupported)
|
||||||
|
{
|
||||||
|
CONTEXT DbgCtx;
|
||||||
|
|
||||||
|
DbgCtx.ContextFlags = CONTEXT_CONTROL;
|
||||||
|
|
||||||
|
hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);
|
||||||
|
|
||||||
|
if (hActiveThread != NULL)
|
||||||
|
{
|
||||||
|
// If TF is set (single step), then suspend all the other threads
|
||||||
|
if (GetThreadContext(hActiveThread, &DbgCtx) && (DbgCtx.EFlags & UE_TRAP_FLAG))
|
||||||
|
{
|
||||||
|
ThreadBeingProcessed = DBGEvent.dwThreadId;
|
||||||
|
|
||||||
|
for (auto& Thread : hListThread)
|
||||||
|
{
|
||||||
|
if (ThreadBeingProcessed == Thread.dwThreadId)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (SuspendThread(Thread.hThread) != -1)
|
||||||
|
SuspendedThreads.push_back(Thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EngineCloseHandle(hActiveThread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continue_dbg_event:
|
||||||
|
|
||||||
if(engineResumeProcessIfNoThreadIsActive)
|
if(engineResumeProcessIfNoThreadIsActive)
|
||||||
{
|
{
|
||||||
if(!ThreaderIsAnyThreadActive())
|
if(!ThreaderIsAnyThreadActive())
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue