some locking

This commit is contained in:
Duncan Ogilvie 2017-12-31 15:13:53 +01:00
parent 3fb8539c7a
commit cd01d22686
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
4 changed files with 67 additions and 6 deletions

View File

@ -107,12 +107,13 @@ namespace GleeBug
ResumeFlag(this)
{
memset(&this->mContext, 0, sizeof(CONTEXT));
InitializeCriticalSection(&mCr);
}
CONTEXT* Registers::GetContext()
LockedPtr<CONTEXT> Registers::GetContext()
{
handleLazyContext();
return &mContext;
return LockedPtr<CONTEXT>(&mCr, &mContext);
}
/*void Registers::SetContext(const CONTEXT & context)
@ -130,6 +131,8 @@ namespace GleeBug
bool Registers::handleLazyContext()
{
ScopedCriticalSection lock(&mCr);
if(!this->mLazySet)
return true;

View File

@ -5,6 +5,63 @@
namespace GleeBug
{
class ScopedCriticalSection
{
PCRITICAL_SECTION cr;
public:
ScopedCriticalSection(PCRITICAL_SECTION cr)
: cr(cr)
{
EnterCriticalSection(cr);
}
~ScopedCriticalSection()
{
LeaveCriticalSection(cr);
}
};
template<class T>
class LockedPtr
{
PCRITICAL_SECTION locker;
T* ptr;
public:
explicit LockedPtr(PCRITICAL_SECTION locker, T* ptr)
: locker(locker), ptr(ptr)
{
EnterCriticalSection(locker);
}
~LockedPtr()
{
LeaveCriticalSection(locker);
}
LockedPtr(const LockedPtr<T> &) = delete;
LockedPtr<T> &operator=(const LockedPtr<T> &) = delete;
LockedPtr(LockedPtr<T> && other)
: locker(other.locker), ptr(other.ptr)
{
other.locker = nullptr;
other.ptr = nullptr;
}
/*operator T*() const
{
return ptr;
}*/
T* operator->() const
{
return ptr;
}
};
/**
\brief Thread register context.
*/
@ -162,7 +219,7 @@ namespace GleeBug
\brief Gets a pointer to the context object.
\return This function will never return a nullptr.
*/
CONTEXT* GetContext();
LockedPtr<CONTEXT> GetContext();
/**
\brief Sets the CONTEXT.
@ -172,6 +229,7 @@ namespace GleeBug
private:
CONTEXT mContext;
CRITICAL_SECTION mCr;
LPCONTEXT mLazyOldContext = nullptr;
HANDLE mLazyThread = nullptr;

View File

@ -284,7 +284,7 @@ namespace GleeBug
bool mBreakDebugger = false;
DEBUG_EVENT mDebugEvent;
ProcessMap mProcesses;
bool mIsRunning = false;
bool mIsRunning = false; //TODO: needs a dedicated critical section to prevent ContinueDebugEvent and change of registers to race
bool mIsDebugging = false;
bool mDetach = false;
bool mDetachAndBreak = false;

View File

@ -533,6 +533,7 @@ public:
if (!thread || !titcontext)
return false;
ThreadSuspender suspender(thread, mIsRunning, false);
auto context = thread->registers.GetContext();
memset(titcontext, 0, sizeof(TITAN_ENGINE_CONTEXT_t));
//General purpose registers
titcontext->cax = thread->registers.Gax();
@ -571,7 +572,6 @@ public:
titcontext->cs = thread->registers.Cs();
titcontext->ss = thread->registers.Ss();
// x87
auto context = thread->registers.GetContext();
#ifdef _WIN64
titcontext->x87fpu.ControlWord = context->FltSave.ControlWord;
titcontext->x87fpu.StatusWord = context->FltSave.StatusWord;
@ -618,6 +618,7 @@ public:
if (!thread || !titcontext)
return false;
ThreadSuspender suspender(thread, mIsRunning, true);
auto context = thread->registers.GetContext();
// General purpose registers
thread->registers.Gax = titcontext->cax;
thread->registers.Gcx = titcontext->ccx;
@ -655,7 +656,6 @@ public:
thread->registers.Cs = titcontext->cs;
thread->registers.Ss = titcontext->ss;
// x87
auto context = thread->registers.GetContext();
#ifdef _WIN64
context->FltSave.ControlWord = titcontext->x87fpu.ControlWord;
context->FltSave.StatusWord = titcontext->x87fpu.StatusWord;