我在一个预先调用C++库的.NET(C#,3.5)应用程序中遇到了一个奇怪的Boost(v1.38)互斥体死锁。在获得读取锁定之后,某个点会[正确]抛出异常,并且该异常一直回到受管理的.NET代码(处理该代码的位置)。在C++库中的下一个呼叫尝试使用setter方法上唯一的锁AQUISITION挂起无限期地(大概是读锁未释放):在抛出异常后未释放Boost共享互斥体
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方法(读者/作家),并实现它们像这样:
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()的调用将在罕见的情况抛出一个异常:
throw std::invalid_argument("Unknown something");
此外, re是getter中的一些对C++库本身的try/catch中的_anotherObject-> GetSomething()进行的调用,防止异常返回到托管代码,并且不会导致此死锁。未处理的异常是否破坏了互斥锁范围的解锁?
在此先感谢任何可能有所洞察的人!
这段代码是用/ clr生效的吗?如果是这样,你是否在它之前放置了#pragma managed(push,off)? –
未使用/ clr开关编译C++。 – roken
这很奇怪,这应该工作。除了实际显示问题的演示程序之外,您唯一的选择是使用/ EHa编译该C++代码。尽管* that *没有任何意义。 –