Delphi DLL没有卸载,可能是由于仍然分配了GDI

时间:2012-04-27 01:26:00

标签: delphi dll delphi-2007

我们编写了一个DLL来执行所有打印功能。它允许我们进行打印预览,打印以及生成PDF。

我们现在有一个特定的使用此DLL的模式,之后DLL无法正确卸载。结果是,当我们退出主程序时,它会消失但不会终止,我们必须手动终止该过程。

我认为罪魁祸首是一些GDI资源没有被正确地“封闭”(当我这样说时,我从GDI的无知深处说出来)。我们不直接处理GDI资源,而是在使用各种Delphi组件时使用GDI资源。

有关如何查找和修复此类问题的任何提示?在我们尝试终止程序之后,我们使用GDIView确认某些GID资源仍然存在,但我不知道如何将这些Windows / Kernel句柄与底层Delphi代码相关联。我可以在程序执行期间的不同时间提供GIDView列表。

谢谢!

Jon(Delphi 2007)


我回复了所提出的建议,但没有人回复我的回复。最终,我放弃了。我最终编写了一个自杀程序,它不仅杀死了我自己的进程,而且还杀死了其他具有相同名称的进程,以解决问题。荒谬的矫枉过正,但我​​似乎别无选择。我正在使用我在某处找到的免费软件ProcessInfo工具。

procedure KillNamedProcesses(pName : String);
// used to clean up programs that hang as a result of DLLs not unloading
   var
      ProcessInfo : TProcessInfo;
      ProcessName : String;
      i : INTEGER;
      currentPID : cardinal;
   BEGIN
   currentPID := GetCurrentProcessID;
   pName := UpperCase(pName);
   ProcessInfo := TProcessInfo.Create(nil);

   // kill all old processes (not our process)
   for i := 0 to ProcessInfo.RunningProcesses.Count - 1 do begin
      ProcessName := ProcessInfo.RunningProcesses[i].ExeFile;
      IF (UpperCase(ProcessName) <> pName) THEN CONTINUE;
      IF (currentPID <> ProcessInfo.RunningProcesses[i].ProcessID) then
         ProcessInfo.RunningProcesses[i].TerminateProcess;
      END;
   // kill the last one (ourselves)
   for i := 0 to ProcessInfo.RunningProcesses.Count - 1 do begin
      ProcessName := ProcessInfo.RunningProcesses[i].ExeFile;
      IF (UpperCase(ProcessName) <> pName) THEN CONTINUE;
      ProcessInfo.RunningProcesses[i].TerminateProcess;
      END;
   ProcessInfo.Free;
   END; // KillNamedProcess

1 个答案:

答案 0 :(得分:5)

您无需返回GDI资源即可关闭进程。当然你应该归还它们,但这不会阻止你终止。这听起来非常像你的DLL卸载死锁。由于您的DLL无法卸载,因此您自然无法释放所有GDI资源。

调试这将涉及调试死锁。对此提出一般性建议相当困难,不幸的是,您使用的是较旧且功能较弱的Delphi版本。现代Delphi调试器支持等待链遍历,并使调试死锁变得相当简单。我想如果我是你,当你的应用程序处于死锁状态时,我会做一些事后调试。我会查看所有线程的堆栈跟踪,并将其用于无论是无限期阻塞的内容。当程序处于死锁状态时,使用Process Explorer和map2dbg来获取有意义的堆栈跟踪。