parent
e2dcda5498
commit
53e621c175
|
@ -13,6 +13,8 @@
|
|||
#include "handle.h"
|
||||
#include "thread.h"
|
||||
#include "GetPeArch.h"
|
||||
#include "database.h"
|
||||
#include "exception.h"
|
||||
|
||||
static bool skipInt3Stepping(int argc, char* argv[])
|
||||
{
|
||||
|
@ -50,11 +52,14 @@ bool cbDebugRunInternal(int argc, char* argv[])
|
|||
|
||||
bool cbDebugInit(int argc, char* argv[])
|
||||
{
|
||||
cbDebugStop(argc, argv);
|
||||
|
||||
static char arg1[deflen] = "";
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return false;
|
||||
|
||||
EXCLUSIVE_ACQUIRE(LockDebugStartStop);
|
||||
cbDebugStop(argc, argv);
|
||||
ASSERT_TRUE(hDebugLoopThread == nullptr);
|
||||
|
||||
static char arg1[deflen] = "";
|
||||
strcpy_s(arg1, argv[1]);
|
||||
wchar_t szResolvedPath[MAX_PATH] = L"";
|
||||
if(ResolveShortcut(GuiGetWindowHandle(), StringUtils::Utf8ToUtf16(arg1).c_str(), szResolvedPath, _countof(szResolvedPath)))
|
||||
|
@ -132,12 +137,21 @@ bool cbDebugInit(int argc, char* argv[])
|
|||
init.commandline = commandline;
|
||||
if(*currentfolder)
|
||||
init.currentfolder = currentfolder;
|
||||
CloseHandle(CreateThread(0, 0, threadDebugLoop, &init, 0, 0));
|
||||
|
||||
hDebugLoopThread = CreateThread(nullptr, 0, threadDebugLoop, &init, CREATE_SUSPENDED, nullptr);
|
||||
ResumeThread(hDebugLoopThread);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cbDebugStop(int argc, char* argv[])
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockDebugStartStop);
|
||||
if(!hDebugLoopThread)
|
||||
return false;
|
||||
|
||||
auto hDebugLoopThreadCopy = hDebugLoopThread;
|
||||
hDebugLoopThread = nullptr;
|
||||
|
||||
// HACK: TODO: Don't kill script on debugger ending a process
|
||||
//scriptreset(); //reset the currently-loaded script
|
||||
_dbg_animatestop();
|
||||
|
@ -145,20 +159,37 @@ bool cbDebugStop(int argc, char* argv[])
|
|||
//history
|
||||
HistoryClear();
|
||||
DWORD BeginTick = GetTickCount();
|
||||
while(waitislocked(WAITID_STOP)) //custom waiting
|
||||
|
||||
while(true)
|
||||
{
|
||||
unlock(WAITID_RUN);
|
||||
Sleep(100);
|
||||
DWORD CurrentTick = GetTickCount();
|
||||
if(CurrentTick - BeginTick > 10000)
|
||||
switch(WaitForSingleObject(hDebugLoopThreadCopy, 100))
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "The debuggee does not stop after 10 seconds. The debugger state may be corrupted."));
|
||||
case WAIT_OBJECT_0:
|
||||
CloseHandle(hDebugLoopThreadCopy);
|
||||
return true;
|
||||
|
||||
case WAIT_TIMEOUT:
|
||||
{
|
||||
unlock(WAITID_RUN);
|
||||
DWORD CurrentTick = GetTickCount();
|
||||
if(CurrentTick - BeginTick > 10000)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "The debuggee does not stop after 10 seconds. The debugger state may be corrupted."));
|
||||
DbSave(DbLoadSaveType::All);
|
||||
TerminateThread(hDebugLoopThreadCopy, 1); // TODO: this will lose state and cause possible corruption if a critical section is still owned
|
||||
CloseHandle(hDebugLoopThreadCopy);
|
||||
return false;
|
||||
}
|
||||
if(CurrentTick - BeginTick >= 300)
|
||||
TerminateProcess(fdProcessInfo->hProcess, -1);
|
||||
}
|
||||
break;
|
||||
|
||||
case WAIT_FAILED:
|
||||
dprintf_untranslated("WAIT_FAILED, GetLastError() = %d (%s)\n", GetLastError(), ErrorCodeToName(GetLastError()).c_str());
|
||||
return false;
|
||||
}
|
||||
if(CurrentTick - BeginTick >= 300)
|
||||
TerminateProcess(fdProcessInfo->hProcess, -1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cbDebugAttach(int argc, char* argv[])
|
||||
|
@ -168,8 +199,11 @@ bool cbDebugAttach(int argc, char* argv[])
|
|||
duint pid = 0;
|
||||
if(!valfromstring(argv[1], &pid, false))
|
||||
return false;
|
||||
if(DbgIsDebugging())
|
||||
DbgCmdExecDirect("stop");
|
||||
|
||||
EXCLUSIVE_ACQUIRE(LockDebugStartStop);
|
||||
cbDebugStop(argc, argv);
|
||||
ASSERT_TRUE(hDebugLoopThread == nullptr);
|
||||
|
||||
Handle hProcess = TitanOpenProcess(PROCESS_ALL_ACCESS, false, (DWORD)pid);
|
||||
if(!hProcess)
|
||||
{
|
||||
|
@ -212,7 +246,8 @@ bool cbDebugAttach(int argc, char* argv[])
|
|||
if(tid)
|
||||
dbgsetresumetid(tid);
|
||||
}
|
||||
CloseHandle(CreateThread(0, 0, threadAttachLoop, (void*)pid, 0, 0));
|
||||
hDebugLoopThread = CreateThread(nullptr, 0, threadAttachLoop, (void*)pid, CREATE_SUSPENDED, nullptr);
|
||||
ResumeThread(hDebugLoopThread);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,6 +91,7 @@ duint maxSkipExceptionCount = 10000;
|
|||
HANDLE mProcHandle;
|
||||
HANDLE mForegroundHandle;
|
||||
duint mRtrPreviousCSP = 0;
|
||||
HANDLE hDebugLoopThread = nullptr;
|
||||
|
||||
static duint dbgcleartracestate()
|
||||
{
|
||||
|
@ -2543,10 +2544,6 @@ void dbgstartscriptthread(CBPLUGINSCRIPT cbScript)
|
|||
|
||||
static void debugLoopFunction(void* lpParameter, bool attach)
|
||||
{
|
||||
//we are running
|
||||
EXCLUSIVE_ACQUIRE(LockDebugStartStop);
|
||||
lock(WAITID_STOP);
|
||||
|
||||
//initialize variables
|
||||
bIsAttached = attach;
|
||||
dbgsetskipexceptions(false);
|
||||
|
@ -2612,7 +2609,6 @@ static void debugLoopFunction(void* lpParameter, bool attach)
|
|||
if(answer == IDYES && dbgrestartadmin())
|
||||
{
|
||||
fdProcessInfo = &g_pi;
|
||||
unlock(WAITID_STOP);
|
||||
GuiCloseApplication();
|
||||
return;
|
||||
}
|
||||
|
@ -2625,7 +2621,6 @@ static void debugLoopFunction(void* lpParameter, bool attach)
|
|||
error += ", uiAccess=\"true\"";
|
||||
}
|
||||
fdProcessInfo = &g_pi;
|
||||
unlock(WAITID_STOP);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Error starting process (CreateProcess, %s)!\n"), error.c_str());
|
||||
return;
|
||||
}
|
||||
|
@ -2636,7 +2631,6 @@ static void debugLoopFunction(void* lpParameter, bool attach)
|
|||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "IsWow64Process failed!"));
|
||||
StopDebug();
|
||||
unlock(WAITID_STOP);
|
||||
return;
|
||||
}
|
||||
if((mewow64 && !wow64) || (!mewow64 && wow64))
|
||||
|
@ -2646,7 +2640,6 @@ static void debugLoopFunction(void* lpParameter, bool attach)
|
|||
#else
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Use x64dbg to debug this process!"));
|
||||
#endif // _WIN64
|
||||
unlock(WAITID_STOP);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2750,7 +2743,7 @@ static void debugLoopFunction(void* lpParameter, bool attach)
|
|||
varset("$pid", (duint)0, true);
|
||||
if(hProcessToken)
|
||||
CloseHandle(hProcessToken);
|
||||
unlock(WAITID_STOP); //we are done
|
||||
|
||||
pDebuggedEntry = 0;
|
||||
pDebuggedBase = 0;
|
||||
pCreateProcessBase = 0;
|
||||
|
|
|
@ -127,5 +127,6 @@ extern duint maxSkipExceptionCount;
|
|||
extern HANDLE mProcHandle;
|
||||
extern HANDLE mForegroundHandle;
|
||||
extern duint mRtrPreviousCSP;
|
||||
extern HANDLE hDebugLoopThread;
|
||||
|
||||
#endif // _DEBUGGER_H
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
enum WAIT_ID
|
||||
{
|
||||
WAITID_RUN,
|
||||
WAITID_STOP,
|
||||
WAITID_LAST
|
||||
};
|
||||
|
||||
|
|
|
@ -752,21 +752,16 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit()
|
|||
*/
|
||||
extern "C" DLL_EXPORT void _dbg_dbgexitsignal()
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Stopping command thread..."));
|
||||
bStopCommandLoopThread = true;
|
||||
MsgFreeStack(gMsgStack);
|
||||
WaitForThreadTermination(hCommandLoopThread);
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Stopping running debuggee..."));
|
||||
cbDebugStop(0, 0);
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Waiting for the debuggee to be stopped..."));
|
||||
if(!waitfor(WAITID_STOP, 10000)) //after this, debugging stopped
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "The debuggee does not close after 10 seconds. Probably the debugger state has been corrupted."));
|
||||
}
|
||||
cbDebugStop(0, 0); //after this, debugging stopped
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Aborting scripts..."));
|
||||
scriptabort();
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Unloading plugins..."));
|
||||
pluginunloadall();
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Stopping command thread..."));
|
||||
bStopCommandLoopThread = true;
|
||||
MsgFreeStack(gMsgStack);
|
||||
WaitForThreadTermination(hCommandLoopThread, 10000);
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Cleaning up allocated data..."));
|
||||
cmdfree();
|
||||
varfree();
|
||||
|
|
Loading…
Reference in New Issue