我在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_CriticalSection
中Foo
的地址。
由于CriticalSectionWrapper
始终在其析构函数中调用DeleteCriticalSection
,并且在释放m_CriticalSection
之前调用了Foo
的析构函数,因此我无法解释报告的关键部分损坏通过AppVerifier。
在清除m_CriticalSection
时,Foo
仍然有效的原因是什么?
答案 0 :(得分:0)
可能只是调用EnterCriticalSection
而没有调用LeaveCriticalSection
。一旦删除它,就不能离开它,因此删除非自由的关键部分是错误的。
还请记住,关键部分是递归的,而不是信号量,这意味着您可以在同一线程中多次输入,但是在同一线程中应该保留相同的次数。