有一个在 dll 中使用的图形库,加载到进程中。似乎库泄漏(在加载/卸载期间,进程资源管理器属性对话框中的 GDI 句柄计数在整个进程中不断增长)。
有没有办法将 dll 创建的所有 GDI 句柄存储在一个进程中,以便在卸载 dll 后将它们全部删除?说,挂钩 CreateBitmap() 等等?但是如何判断资源是不是我们的dll创建的,而不是进程本身呢?
问候,
有一个在 dll 中使用的图形库,加载到进程中。似乎库泄漏(在加载/卸载期间,进程资源管理器属性对话框中的 GDI 句柄计数在整个进程中不断增长)。
有没有办法将 dll 创建的所有 GDI 句柄存储在一个进程中,以便在卸载 dll 后将它们全部删除?说,挂钩 CreateBitmap() 等等?但是如何判断资源是不是我们的dll创建的,而不是进程本身呢?
问候,
Is there a way to store all GDI handles created by the dll in a process to delete them all after the dll is unloaded? Say, hook CreateBitmap() and so on? But how to determine whether the resource is being created by our dll, not the process itself?
No. You are going to need to fix this problem at source. If the DLL really is leaking handles, you have to fix the DLL.
关闭由 DLL 打开的所有句柄并释放所有资源的方法是使用一个单独的进程,该进程加载 DLL 并在 DLL 卸载后终止。因此,您可以评估哪个工作量更大:修复 DLL,找到另一个 DLL(不会泄漏并且可能没有很多其他陷阱),或者实现进程间通信以释放句柄并仍然使用动态链接库。如果您选择后一种方式,您可以使用共享内存块在进程之间传输绘制的位图,使用命名事件进行同步等。
要确定调用者必须获取每个调用的堆栈跟踪,请查看RtlCaptureStackBackTrace。
我会尝试做的另一种方法是修改这个 DLL(我假设你只有一个 DLL 二进制文件,而不是源代码:否则你可以修复泄漏)以使其使用 GDI33.DLL 而不是 GDI32.dll。然后您创建 GDI33.DLL 导出该 dll 使用的那些函数。GDI33.DLL 将调用转发到 GDI32.dll 并收集 GDI 对象句柄。