CRT区域关键部分的死锁

时间:2015-05-08 13:18:07

标签: c++ visual-studio visual-c++ windbg msvcrt

讨论应用程序错误:

很少大多数应用程序线程都会遇到相同的重复死锁。死锁在Windows XP和后者上每月复制一次。

关于我们的大型项目必不可少:

在客户机器上复制错误时,项目构建为发布目标。

使用/ EHa编译的应用程序因此带有省略号(...)的catch块有时可能会隐藏访问冲突和其他系统异常。 (请不要用省略号讨论好或坏练习捕获块)。

项目由纯粹的纯CLR和混合CLR程序集组成(C ++; C#; C ++ \ CLI)。

MSVS 2013

大多数应用程序线程使用线程本地C语言环境模式。

WinDbg dump info, most essential

WinDbg dump info, full stack traces

Full dump (70Mb)

大多数线程在CRT源上等待CRT区域设置关键部分(“_ mlock(_SETLOCALE_LOCK)”代码),例如WinDbg_ID = 44的线程。

等待加载程序关键部分的其他线程,例如WinDbg_ID = 23的线程。

可能有23个线程在CRT源内部输入到CRT区域关键部分并且没有离开它。

44线程在_CRTDLL_INIT / dllmain之前进入加载程序关键部分,并在执行DLL_THREAD_ATTACH时等待_CRTDLL_INIT / dllmain的crt-locale临界区。

dllmain是默认生成的。

必须保留区域设置关键部分,因为_munlock(_SETLOCALE_LOCK)应该在__最终阻止CRT源。

在输入CRT语言环境关键部分并且_munlock未离开CRT语言环境关键部分时,可能会发生一些系统异常。

异常排序:正在处理的3个模块:

  • msvcr80.dll - 由sqlncli10.dll
  • 加载
  • msvcr120.dll
  • msvcr120_clr0400.dll

问题:

有人有想法或解释吗?

是否可以从单个线程调用来自不同CRT版本的CRT语言环境功能?由于CRT差异,这可能会破坏线程本地CRT区域设置数据存储器。在进入CRT区域关键部分后发生了一些系统异常。这是真的吗?

是否可以跳过__finally阻止?跳过场景?

1 个答案:

答案 0 :(得分:3)

可能我们找到了答案,并将在实践中对此进行测试。

我们在向量异常处理程序中的每个非c ++异常上运行backtrace logger,并在发生时捕获堆栈跟踪。锁定区域设置CS后的访问冲突。

我们以多线程方式将第三方库ZipArchive用于我们的项目。在这个库函数深入的CZipString :: MakeLower \ CZipString :: MakeUpper使本地静态变量std :: locale,这是多线程情况下C ++ 98 / MsVs 2013的UB。它很少会破坏堆栈顶部并在代码段中调用随机代码,而无需正确展开堆栈并且不使用离开区域设置CS。发生访问违规,线程状态由/ EHa“恢复”并捕获(...)。在不正确的堆栈展开后,线程卡在另一个CS上。

谢谢大家。