释放包含活动临界区的堆块

时间:2014-10-07 17:20:19

标签: c++ windows multithreading critical-section

我在AppVerifier和WinDBG下运行了我的Windows应用程序(Service.exe)的'基础'测试,调试器打破了此消息

=======================================
VERIFIER STOP 0000000000000202: pid 0x2004EC: Freeing heap block containing an active critical section. 

    00000088A4097F28 : Critical section address. Run !cs -s <address> to get more information.
    00000088F6CA9580 : Critical section initialization stack trace. Run dps <address> to dump the stack trace.
    00000088A4097E70 : Heap block address.
    0000000000000188 : Heap block size.
=======================================

当前堆栈跟踪显示正在释放对象Foo

00 000000f9`0cf0f300 00007ff8`5d32674f vrfcore!VerifierStopMessageEx+0x6db 
01 000000f9`0cf0f660 00007ff8`5d324a2c vfbasics!AVrfpFreeMemLockChecks+0xef 
02 000000f9`0cf0f6c0 00007ff8`5d332188 vfbasics!AVrfpFreeMemNotify+0x38 
03 000000f9`0cf0f6f0 00007ff8`4d6eb13f vfbasics!AVrfpHeapFree+0x98 
04 000000f9`0cf0f780 00007ff8`4d70086d MSVCR120D!_free_base+0x2f 
05 000000f9`0cf0f7c0 00007ff8`4d700196 MSVCR120D!_free_dbg_nolock+0x6bd 
06 000000f9`0cf0f830 00007ff8`4d701e68 MSVCR120D!_free_dbg+0x26 
07 000000f9`0cf0f860 00007ff6`1c088707 MSVCR120D!free+0x18 
08 000000f9`0cf0f890 00007ff6`1beeb933 Service!DeleteImpl+0x37 
09 000000f9`0cf0f8c0 00007ff6`1c0474ac Service!operator delete+0x13
0a 000000f9`0cf0f8f0 00007ff6`1c04767e Service!Foo::`scalar deleting destructor'+0x2c

对象Foo包含CRITICAL_SECTION

上的包装器
class Foo
{    
    // Some other members here   

    CriticalSectionWrapper m_CriticalSection;
}

class CriticalSectionWrapper
{
    CRITICAL_SECTION m_cs;

public:

    CriticalSectionWrapper() { InitializeCriticalSection(&m_cs); }
    ~CriticalSectionWrapper() { DeleteCriticalSection(&m_cs); }

    _Acquires_lock_(&m_cs) void Enter(void) { EnterCriticalSection(&m_cs); }
    _Releases_lock_(&m_cs) void Leave(void) { LeaveCriticalSection(&m_cs); }
}

地址00000088A4097F28(AppVerifier报告的主动关键部分)是m_CriticalSectionFoo的地址。

由于CriticalSectionWrapper始终在其析构函数中调用DeleteCriticalSection,并且在释放m_CriticalSection之前调用了Foo的析构函数,因此我无法解释报告的关键部分损坏通过AppVerifier。

在清除m_CriticalSection时,Foo仍然有效的原因是什么?

1 个答案:

答案 0 :(得分:0)

可能只是调用EnterCriticalSection而没有调用LeaveCriticalSection。一旦删除它,就不能离开它,因此删除非自由的关键部分是错误的。

还请记住,关键部分是递归的,而不是信号量,这意味着您可以在同一线程中多次输入,但是在同一线程中应该保留相同的次数。