【发布时间】:2019-05-18 00:49:49
【问题描述】:
问题目的:对MS docs of DllMain进行现实检查。
“常识”是你不应该在 DllMain 中做太多事情,有些事情绝对不能做,一些 best practises。
我现在偶然发现了文档中的一个新宝石,这对我来说毫无意义:(emph. mine)
在处理
DLL_PROCESS_DETACH时,DLL 应该释放资源,例如 仅当动态卸载 DLL 时才堆内存(lpReserved参数为 NULL)。如果进程正在终止( lpvReserved 参数为非NULL),进程中的所有线程除了 当前线程已经退出或已明确退出 通过调用ExitProcess函数终止,这可能会离开 某些进程资源,例如堆处于不一致状态。在这个 在这种情况下,DLL 清理资源是不安全的。反而, DLL 应该允许操作系统回收内存。
由于全局 C++ 对象在 DllMain/DETACH 期间被清理,这意味着全局 C++ 对象不得释放任何动态内存,因为堆可能处于不一致状态。 / 当 DLL “静态链接”到可执行文件时。 / 当然不是我在那里看到的 - 各种(我们的和第三方的)库的全局 C++ 对象(如果有)在它们的析构函数中分配和解除分配就好了。 (除非其他排序错误,o.c.)
那么,这个警告针对的是什么具体的技术问题?
既然段落提到了线程终止,那么当某些线程没有被正确清理时会不会出现堆损坏问题?
【问题讨论】:
-
当他们接到太多的支持电话时,就会添加这种措辞。记录未记录参数的唯一原因。一个示例场景是程序员使用 SetUnhandledExceptionFilter(),做一些有用的事情来帮助诊断崩溃,然后用 ExitProcess 而不是 TerminateProcess。在测试时总是有效,但在现实世界中崩溃是由堆损坏引起的并且堆锁仍然被持有时,这很糟糕。
标签: winapi visual-c++ dll entry-point dllmain