为什么不能从DllMain函数调用CreateProcess?

时间:2014-11-05 09:50:36

标签: winapi createprocess dllmain

我在几个来源中读到,CreateProcess函数不能调用DllMain

CreateProcess

不要从DllMain函数调用CreateProcess。这会导致应用程序停止响应。

Dynamic-Link Library Best Practices

您永远不应该在DllMain中执行以下任务: 调用CreateProcess。创建进程可以加载另一个DLL。

问题

为什么?它声明它导致应用程序停止响应,但这只是一个症状。真正的原因是什么?

我问的原因是我尝试从DllMain函数创建一个进程,它看起来工作正常。

2 个答案:

答案 0 :(得分:4)

加载锁定时,

DllMain执行。正如您引用的文档所解释的那样,CreateProcess可能会导致加载DLL。这可能会导致装载机锁定死锁。发生死锁是因为加载器锁已经被保持。

文档很清楚。不要从CreateProcess致电DllMain。从DllMain完成任务的标准方法是创建一个线程来完成工作。虽然你不能在那个线程上等待,因为这导致完全相同的死锁。

答案 1 :(得分:1)

MSDN says

  

因此,入口点函数可以调用Kernel32.dll中不加载其他DLL的函数。 [...]不幸的是,Kernel32.dll中没有安全功能的完整列表。

然后它扩展了声明,解释了更复杂的API(包括CreateProcess)可能涉及usafe API调用:

  

调用需要除Kernel32.dll之外的DLL的函数可能会导致难以诊断的问题。例如,调用User,Shell和COM函数可能会导致访问冲突错误,因为某些函数会加载其他系统组件。相反,在终止期间调用这些函数会导致访问冲突错误,因为相应的组件可能已经被卸载或未初始化。

这就是最佳实践的背后建议不要调用CreateProcess。 CreateProcess是否将加载其他DLL是您无法控制的。您的控制是避免不安全的API调用并在以后创建进程。