1
0
Fork 0

DBG: fixed a deadlock with handling of unknown breakpoints (closes issue #1546)

This commit is contained in:
mrexodia 2017-04-19 21:47:38 +02:00
parent 171eca3be6
commit 4c1fd6ca09
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
2 changed files with 16 additions and 9 deletions

View File

@ -903,7 +903,8 @@ static void cbGenericBreakpoint(BP_TYPE bptype, void* ExceptionAddress = nullptr
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
auto CIP = GetContextDataEx(hActiveThread, UE_CIP);
BREAKPOINT* bpPtr = nullptr;
SHARED_ACQUIRE(LockBreakpoints);
//NOTE: this locking is very tricky, make sure you understand it before modifying anything
EXCLUSIVE_ACQUIRE(LockBreakpoints);
switch(bptype)
{
case BPNORMAL:
@ -928,6 +929,8 @@ static void cbGenericBreakpoint(BP_TYPE bptype, void* ExceptionAddress = nullptr
{
if(bptype != BPDLL || !BpUpdateDllPath(reinterpret_cast<const char*>(ExceptionAddress), &bpPtr))
{
// release the breakpoint lock to prevent deadlocks during the wait
EXCLUSIVE_RELEASE();
dputs(QT_TRANSLATE_NOOP("DBG", "Breakpoint reached not in list!"));
DebugUpdateGuiSetStateAsync(GetContextDataEx(hActiveThread, UE_CIP), true);
//lock
@ -945,8 +948,10 @@ static void cbGenericBreakpoint(BP_TYPE bptype, void* ExceptionAddress = nullptr
// increment hit count
InterlockedIncrement((volatile long*)&bpPtr->hitcount);
// copy the breakpoint structure and release the breakpoint lock to prevent deadlocks during the wait
auto bp = *bpPtr;
SHARED_RELEASE();
EXCLUSIVE_RELEASE();
if(bptype != BPDLL && bptype != BPEXCEPTION)
bp.addr += ModBaseFromAddr(CIP);
bp.active = true; //a breakpoint that has been hit is active

View File

@ -74,8 +74,7 @@ enum SectionLock
LockModuleHashes,
LockFormatFunctions,
// Number of elements in this enumeration. Must always be the last
// index.
// Number of elements in this enumeration. Must always be the last index.
LockLast
};
@ -168,22 +167,25 @@ public:
if(m_LockCount > 0)
Unlock();
#ifdef _DEBUG
// Assert that the lock count is zero on destructor
if(m_LockCount > 0)
__debugbreak();
#endif
// The lock count should be zero after destruction.
assert(m_LockCount == 0);
}
inline void Lock()
{
Internal::AcquireLock(LockIndex, Shared);
// We cannot recursively lock more than 255 times.
assert(m_LockCount < 255);
m_LockCount++;
}
inline void Unlock()
{
// Unlocking twice will cause undefined behaviour.
assert(m_LockCount != 0);
m_LockCount--;
Internal::ReleaseLock(LockIndex, Shared);