【发布时间】:2015-05-08 13:18:06
【问题描述】:
讨论应用程序错误:
很少有大多数应用程序线程陷入相同重复的死锁。死锁在 Windows XP 和更高版本上大约每月重现一次。
关于我们大型项目的基本信息:
在客户机器上重现错误时作为发布目标构建的项目。
使用 /EHa 编译的应用程序因此使用省略号 (...) 捕获块有时可能会隐藏访问冲突和其他系统异常。 (请不要用省略号讨论 catch 块的好坏)。
项目由纯 CLR 和混合 CLR 程序集 (C++;C#;C++\CLI) 组成。
MSVS 2013
大多数应用程序线程使用线程本地 C 语言环境模式。
WinDbg dump info, most essential
WinDbg dump info, full stack traces
在 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 源的 __finally 块。
在 CRT 语言环境临界区进入后和 _munlock 未离开 CRT 语言环境临界区时可能发生了一些系统异常。
有点不寻常:进程中有 3 个模块:
- msvcr80.dll - 由 sqlncli10.dll 加载
- msvcr120.dll
- msvcr120_clr0400.dll
问题:
有人有什么想法或解释吗?
是否可以从单线程调用来自不同 CRT 版本的 CRT 语言环境函数?由于 CRT 差异,这可能会破坏线程本地 CRT 语言环境数据内存。进入 CRT 语言环境临界区后出现一些系统异常。是真的吗?
是否可以跳过 __finally 块?跳过场景?
【问题讨论】:
-
你有一些使用
CreateThread()的代码吗?您应该用_beginthreadex()替换它(或类似的东西,请参阅文档)。对于这三个 MSVCR 库,使用“dependency walker”检查依赖树,看看它们是否被同一个模块直接使用。如果是这样,那肯定是错误的,如果不是,它仍然可能是错误的,但不是必须的。 -
存在 大量 数量的死锁,种类繁多,而不仅仅是语言环境。好像炸弹爆炸了。您无法在此处获得帮助。
-
@UlrichEckhardt 我们的代码不使用 CreateThread。 std::thread 和 pplx::task 主要是。
-
@HansPassant 这里只是对死锁的一种简单解释:CRT 语言环境临界区没有离开,什么时候应该离开。
标签: c++ visual-studio visual-c++ windbg msvcrt