Windows VS控制台中的应用程序验证程序报告和错误:删除具有无效锁计数的关键节

Windows VS控制台中的应用程序验证程序报告和错误:删除具有无效锁计数的关键节,windows,multithreading,mutex,critical-section,Windows,Multithreading,Mutex,Critical Section,我打开了appverif.exe,将二进制文件添加到列表中,并启用了“基本”测试。保存更改后,我使用VisualStudio以调试模式打开了应用程序。更准确地说,我首先启动了服务(应用程序是一个作为系统运行的服务,因此我需要稍后附加到它),然后将VS调试器附加到进程 有时,应用程序在DeleteCriticalSection之后崩溃,VS控制台窗口中显示以下消息: VERIFIER STOP 00000208 - Deleting critical section with invalid lo

我打开了appverif.exe,将二进制文件添加到列表中,并启用了“基本”测试。保存更改后,我使用VisualStudio以调试模式打开了应用程序。更准确地说,我首先启动了服务(应用程序是一个作为系统运行的服务,因此我需要稍后附加到它),然后将VS调试器附加到进程

有时,应用程序在
DeleteCriticalSection
之后崩溃,VS控制台窗口中显示以下消息:

VERIFIER STOP 00000208 - Deleting critical section with invalid lock count
    05AAEB48 : Critical section address. Run !cs -s <address> to get more information.
验证程序停止00000208-删除具有无效锁计数的关键部分
05AAEB48:关键区段地址。跑cs-s获取更多信息。
我想这意味着
CRITICAL_部分
变量已被删除,而另一个线程对其进行了锁定。对吗

如何避免这样的问题

我知道理想的工具是引用计数器,这样只有拥有指针最后一次引用的人才能删除对象。这已经在C++11及更高版本中实现,但不是在纯C中实现的

缓解措施可能是注册每个第一次使用该变量的线程。当一个线程想要删除变量时,它首先检查队列是否只包含它的id,如果是这种情况,则删除已完成,否则需要删除队列中的最后一个线程。当然,该变量可能仍被从未使用过它的线程使用,因此该线程尚未注册到队列,仍然可以调用变量上的
EnterCriticalSection
,并导致崩溃。另一个问题是,您需要使用另一个
CRITICAL_SECTION
变量来保护队列访问(至少是写访问),这样您就可以将问题从一个变量转移到另一个变量


有什么想法吗?

很好的提示,但是……我怎么能做到呢?不幸的是,我没有设计这个应用程序,所以也很难找出什么是设计缺陷。还很难控制哪些线程仍然有对
CRITICAL\u部分的引用,并且可以调用
EnterCriticalSection
。这就是为什么我认为解决这个问题的唯一方法是使用带有引用计数器的指针对象。由于我可以在这个纯C应用程序中引入并成功编译C++代码,所以我会去做。不幸的是,我不能使用C++11,因为应用程序是交叉编译的,并且不是所有的编译器都支持这个版本。无论如何,我认为实现这样的类并不是那么困难。我在这里找到了一个很好的示例: