【问题标题】:Deadlock on CRT locale critical sectionCRT 语言环境关键部分的死锁
【发布时间】: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

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 源的 __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


【解决方案1】:

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

我们在向量异常处理程序中对每个非 c++ 异常运行回溯记录器,并在它发生时捕获堆栈跟踪。锁定区域设置 CS 后访问冲突。

我们以多线程方式在我们的项目中使用了第三方库 ZipArchive。在 CZipString::MakeLower\CZipString::MakeUpper 深处的这个库函数中,生成局部静态变量 std::locale,这是多线程情况下 C++98/MsVs 2013 的 UB。它很少只是破坏堆栈顶部并在代码部分调用随机代码而没有正确展开堆栈并且没有离开区域设置 CS。然后发生访问冲突,线程的状态由 /EHa 和 catch(...) “恢复”。比不正确的堆栈展开后线程卡在另一个 CS 上。

谢谢大家。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-25
    相关资源
    最近更新 更多