Boost共享互斥体在异常抛出后不会释放 [英] Boost shared mutex not released after exception thrown

查看:152
本文介绍了Boost共享互斥体在异常抛出后不会释放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个预先存在的.NET(C#,3.5)应用程序中遇到了一个奇怪的Boost(v1.38)互斥锁死锁,该应用程序调用了C ++库。在获得读取锁定之后的某一时刻,[正确]抛出一个异常,并且该异常一直未处理,直到返回到受管理的.NET代码(在其中被处理)。下一次调用试图使用setter方法的c ++库会无限期地挂起唯一锁定(可能读取锁未释放):

I came across a strange Boost (v1.38) mutex deadlock in a preexisting .NET (C#, 3.5) application that makes calls to a C++ library. An exception is [properly] thrown at a point after a read lock is obtained and that exception goes unhandled all the way back to the managed .NET code (where it is handled). The next call to the c++ library that attempts to use a setter method hangs on the unique lock aquisition indefinately (presumably the read lock was not released):

ntdll.dll!NtWaitForSingleObject() + 0x15 bytes 
kernel32.dll!WaitForSingleObjectEx() + 0x43 bytes 
kernel32.dll!WaitForSingleObject() + 0x12 bytes 
OurCPPLib.dll!boost::shared_mutex::unlock_upgrade_and_lock() Line 478 + 0x11 bytes C++ 
OurCPPLib.dll!boost::unique_lock<boost::shared_mutex>::unique_lock<boost::shared_mutex>(boost::detail::thread_move_t<boost::upgrade_lock<boost::shared_mutex> > other) Line 788 C++ 
OurCPPLib.dll!boost::upgrade_to_unique_lock<boost::shared_mutex>::upgrade_to_unique_lock<boost::shared_mutex>(boost::upgrade_lock<boost::shared_mutex> & m_) Line 802 + 0x98 bytes C++ 
OurCPPLib.dll!OurClass::SetSomething(double something) Line 95 C++ 

类定义了多个Get和Set方法(读者/作者),并实现它们:

The class defines a number of Get and Set methods (readers/writers) and implements them like so:

boost::shared_mutex _calcSharedMutex;

RETURNCODE GetSomething(double& something)
{
    boost::shared_lock<boost::shared_mutex> lock(_calcSharedMutex);
    return _anotherObject->GetSomething(something);
}

RETURNCODE SetSomething(double something)
{
    boost::upgrade_lock<boost::shared_mutex> lock(_calcSharedMutex);
    boost::upgrade_to_unique_lock<boost::shared_mutex> uniqueLock(lock);
    return _anotherObject->SetSomething(something);
}

调用_anotherObject-> GetSomething条件:

The call to _anotherObject->GetSomething() will throw an exception in a rare condition:

throw std::invalid_argument("Unknown something");

此外,在getter中有一些调用_anotherObject-> GetSomething / catch在C ++库本身,防止异常返回到托管代码,并且不会导致这种死锁。

Also, there are some calls within getters to _anotherObject->GetSomething() that are made within a try/catch in the C++ library itself, preventing the exception from going back to the managed code, and that does not cause this deadlock. Does the unhandled exception break the boost mutex scope unlocking?

提前感谢任何可能有一些洞察力的人。

Thanks in advance to anyone that may have some insight!

推荐答案

在托管代码中处理本机出现异常时,2.0 CLR中存在一个错误,可防止堆栈释放。

There is a bug in the 2.0 CLR that prevents the stack from unwinding when the native-born exception is handled in managed code.

Microsoft Connect:/ Ehsc& / Eha&堆栈展开

将管理可执行文件切换到在4.0 CLR上运行可以纠正问题。

Switching the managed executable to run on the 4.0 CLR corrected the problem.

作为附注,本地C ++库正在从一个托管的C#库中调用,该库以2.0 CLR为目标。托管程序集可以继续定位2.0 CLR,因为它将在可执行文件的无错误CLR(4.0)上执行,但它将以2.0兼容模式执行。

As a side note, the native C++ library was being called from a managed C# library which was targeting the 2.0 CLR. The managed assembly can continue to target the 2.0 CLR since it will execute on the bug-free CLR of the executable (4.0), but it will be executed in a 2.0 compatability mode.

这篇关于Boost共享互斥体在异常抛出后不会释放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆