我需要 WOW64 转储来进行 GDI 句柄分析吗?
Do I need a WOW64 dump for GDI Handle analysis?
我正在调试潜在的 GDI 句柄泄漏。感谢 @Alois Kraus, there is a WinDbg script 执行句柄计数。
从我的调试会话中,especially for .NET,我发现通常,最好有 32 位进程的 32 位转储和 64 位进程的 64 位转储。
不幸的是,我收到了 2 个故障转储,脚本无法运行。深入研究,我发现 GdiSharedHandleTable 在那些转储中是 null
:
0:000> dt ntdll!_PEB GdiSharedHandleTable @$peb
+0x094 GdiSharedHandleTable : (null)
现在,在 his website 上,Alois 提到了
Important: If you are running on a 64 bit OS you need to attach the 64-bit Windbg even if you debug a 32-bit application!
不幸的是,在 32 位故障转储上使用 64 位 WinDbg 没有帮助。结果还是一样
现在有一个理论:
- 32 位进程中的某些 DLL 是 64 位 DLL(请参阅 Windows Internals 5,第 3 章,"System mechanisms," 第 211 页)
ntdll
就是其中之一(加载了两次,在64位版本和32位版本)
- 虽然 GDI 对象是用户对象(而不是内核对象),但它们仍然需要由 OS 绘制等。因此可能需要在 WOW64 层中管理它们
- 这意味着我必须有一个 WOW64 故障转储才能使其工作
所以我的问题是:我是否遇到需要 WOW64 崩溃转储的罕见情况? 如果能对我的理论进行更详细的解释,那就太好了。如果某本书中已经有很好的解释,那么参考该章就足够了。还没有我就买
对于 GDI 句柄转储,您需要进行 64 位转储,即使它是 Win64 计算机上的 32 位进程。如果您在 64 位机器上进行 32 位转储,则指向 GDI 共享句柄 table 的指针为空。看起来此信息仅为 64 位转储捕获。
这是有道理的,因为您需要在 32 位进程中处理 64 位指针,因为进程的 GDI 句柄 table 部分从内核 space 映射到您的地址 space。我想这样做是为了与 32 位进程应该只包含相同位数的指针的规则保持一致。
如果转储是在进程到达其 WinMain / Main /WinmainCrtStartup / Etc 之前进行的
也就是说,如果初始化代码不是 运行 那么 GdiSharedHandleTable 可以是 null
在正常运行期间崩溃的转储不是这种情况,但需要注意一点
例如,如果您在 windbg 中启动 calc.exe 并在第一次系统中断时检查 GdiSharedHandleTable GdiSharedHandle 可以为 NULL
但如果您在 @$exentry 或 calc!WinMain 上设置中断,将会被填充
生成此输出的脚本已作为对 linked thread
的回答发布
0:000> dd @@c++(@$Peb->GdiSharedHandleTable)
00000000 ???????? ???????? ???????? ????????
00000010 ???????? ???????? ???????? ????????
00000020 ???????? ???????? ???????? ????????
00000030 ???????? ???????? ???????? ????????
00000040 ???????? ???????? ???????? ????????
00000050 ???????? ???????? ???????? ????????
00000060 ???????? ???????? ???????? ????????
00000070 ???????? ???????? ???????? ????????
0:000> g calc!WinMain
calc!WinMain:
00591635 8bff mov edi,edi
0:000> dd @@c++(@$Peb->GdiSharedHandleTable)
00470000 00000000 00000000 40000000 00000000
00470010 00000000 00000000 00000000 00000000
00470020 00000000 00000000 00000000 00000000
00470030 00000000 00000000 00000000 00000000
00470040 00000000 00000000 00000000 00000000
00470050 00000000 00000000 00000000 00000000
00470060 00000000 00000000 00000000 00000000
00470070 00000000 00000000 00000000 00000000
0:000> $$>a< c:\wdscr\dumpgdi.txt
gdioffs Kaddr Pid Count Handle Type Tname IsLive UAddr
00472b30 fe6b5728 00000ca4 00000000 0d0102b3 00000001 DC 00000040 000e0cb0
00472be0 fdf73da8 00000ca4 00000000 420502be 00000005 Bitmap 00000040 00000000
004737b0 fddac108 00000ca4 00000000 9605037b 00000005 Bitmap 00000040 00000000
00474030 fe76eda8 00000ca4 00000000 eb050403 00000005 Bitmap 00000040 00000000
00474c90 fddde008 00000ca4 00000000 d70a04c9 0000000a Font 00000040 001fb1e8
0047ab80 fddab008 00000ca4 00000000 ba050ab8 00000005 Bitmap 00000040 00000000
0047f270 fddbcda8 00000ca4 00000000 16050f27 00000005 Bitmap 00000040 00000000
0047fef0 fdee4da8 00000ca4 00000000 cd050fef 00000005 Bitmap 00000040 00000000
004809f0 fe72eda8 00000ca4 00000000 3405109f 00000005 Bitmap 00000040 00000000
00480e50 fdda5aa8 00000ca4 00000000 0e0510e5 00000005 Bitmap 00000040 00000000
00481cf0 ffb0fda8 00000ca4 00000000 df0511cf 00000005 Bitmap 00000040 00000000
00481d70 fddb0da8 00000ca4 00000000 930511d7 00000005 Bitmap 00000040 00000000
00482020 ff4a1da8 00000ca4 00000000 d4051202 00000005 Bitmap 00000040 00000000
00482060 fddd4008 00000ca4 00000000 39051206 00000005 Bitmap 00000040 00000000
00482170 fddb6008 00000ca4 00000000 20051217 00000005 Bitmap 00000040 00000000
00483140 ff4a0008 00000ca4 00000000 4e051314 00000005 Bitmap 00000040 00000000
00483870 ff427980 00000ca4 00000000 6d051387 00000005 Bitmap 00000040 00000000
00483d80 fe7d04b0 00000ca4 00000000 bd0513d8 00000005 Bitmap 00000040 00000000
00484620 ff437eb8 00000ca4 00000000 0d101462 00000010 Brush 00000040 000f0fd8
004846a0 fddc2da8 00000ca4 00000000 d305146a 00000005 Bitmap 00000040 00000000
00484b80 fdf1a728 00000ca4 00000000 530114b8 00000001 DC 00000040 000e0ae0
Gdi Handles for C:\Windows\system32\calc.exe
Total Gdi Handles = 21
DC = 2
Font = 0
Region = 17
Brush = 0
Bitmap = 1
Pen = 1
Pallete = 0
Unknpown = 0
我正在调试潜在的 GDI 句柄泄漏。感谢 @Alois Kraus, there is a WinDbg script 执行句柄计数。
从我的调试会话中,especially for .NET,我发现通常,最好有 32 位进程的 32 位转储和 64 位进程的 64 位转储。
不幸的是,我收到了 2 个故障转储,脚本无法运行。深入研究,我发现 GdiSharedHandleTable 在那些转储中是 null
:
0:000> dt ntdll!_PEB GdiSharedHandleTable @$peb
+0x094 GdiSharedHandleTable : (null)
现在,在 his website 上,Alois 提到了
Important: If you are running on a 64 bit OS you need to attach the 64-bit Windbg even if you debug a 32-bit application!
不幸的是,在 32 位故障转储上使用 64 位 WinDbg 没有帮助。结果还是一样
现在有一个理论:
- 32 位进程中的某些 DLL 是 64 位 DLL(请参阅 Windows Internals 5,第 3 章,"System mechanisms," 第 211 页)
ntdll
就是其中之一(加载了两次,在64位版本和32位版本)- 虽然 GDI 对象是用户对象(而不是内核对象),但它们仍然需要由 OS 绘制等。因此可能需要在 WOW64 层中管理它们
- 这意味着我必须有一个 WOW64 故障转储才能使其工作
所以我的问题是:我是否遇到需要 WOW64 崩溃转储的罕见情况? 如果能对我的理论进行更详细的解释,那就太好了。如果某本书中已经有很好的解释,那么参考该章就足够了。还没有我就买
对于 GDI 句柄转储,您需要进行 64 位转储,即使它是 Win64 计算机上的 32 位进程。如果您在 64 位机器上进行 32 位转储,则指向 GDI 共享句柄 table 的指针为空。看起来此信息仅为 64 位转储捕获。
这是有道理的,因为您需要在 32 位进程中处理 64 位指针,因为进程的 GDI 句柄 table 部分从内核 space 映射到您的地址 space。我想这样做是为了与 32 位进程应该只包含相同位数的指针的规则保持一致。
如果转储是在进程到达其 WinMain / Main /WinmainCrtStartup / Etc 之前进行的
也就是说,如果初始化代码不是 运行 那么 GdiSharedHandleTable 可以是 null
在正常运行期间崩溃的转储不是这种情况,但需要注意一点
例如,如果您在 windbg 中启动 calc.exe 并在第一次系统中断时检查 GdiSharedHandleTable GdiSharedHandle 可以为 NULL
但如果您在 @$exentry 或 calc!WinMain 上设置中断,将会被填充
生成此输出的脚本已作为对 linked thread
的回答发布0:000> dd @@c++(@$Peb->GdiSharedHandleTable)
00000000 ???????? ???????? ???????? ????????
00000010 ???????? ???????? ???????? ????????
00000020 ???????? ???????? ???????? ????????
00000030 ???????? ???????? ???????? ????????
00000040 ???????? ???????? ???????? ????????
00000050 ???????? ???????? ???????? ????????
00000060 ???????? ???????? ???????? ????????
00000070 ???????? ???????? ???????? ????????
0:000> g calc!WinMain
calc!WinMain:
00591635 8bff mov edi,edi
0:000> dd @@c++(@$Peb->GdiSharedHandleTable)
00470000 00000000 00000000 40000000 00000000
00470010 00000000 00000000 00000000 00000000
00470020 00000000 00000000 00000000 00000000
00470030 00000000 00000000 00000000 00000000
00470040 00000000 00000000 00000000 00000000
00470050 00000000 00000000 00000000 00000000
00470060 00000000 00000000 00000000 00000000
00470070 00000000 00000000 00000000 00000000
0:000> $$>a< c:\wdscr\dumpgdi.txt
gdioffs Kaddr Pid Count Handle Type Tname IsLive UAddr
00472b30 fe6b5728 00000ca4 00000000 0d0102b3 00000001 DC 00000040 000e0cb0
00472be0 fdf73da8 00000ca4 00000000 420502be 00000005 Bitmap 00000040 00000000
004737b0 fddac108 00000ca4 00000000 9605037b 00000005 Bitmap 00000040 00000000
00474030 fe76eda8 00000ca4 00000000 eb050403 00000005 Bitmap 00000040 00000000
00474c90 fddde008 00000ca4 00000000 d70a04c9 0000000a Font 00000040 001fb1e8
0047ab80 fddab008 00000ca4 00000000 ba050ab8 00000005 Bitmap 00000040 00000000
0047f270 fddbcda8 00000ca4 00000000 16050f27 00000005 Bitmap 00000040 00000000
0047fef0 fdee4da8 00000ca4 00000000 cd050fef 00000005 Bitmap 00000040 00000000
004809f0 fe72eda8 00000ca4 00000000 3405109f 00000005 Bitmap 00000040 00000000
00480e50 fdda5aa8 00000ca4 00000000 0e0510e5 00000005 Bitmap 00000040 00000000
00481cf0 ffb0fda8 00000ca4 00000000 df0511cf 00000005 Bitmap 00000040 00000000
00481d70 fddb0da8 00000ca4 00000000 930511d7 00000005 Bitmap 00000040 00000000
00482020 ff4a1da8 00000ca4 00000000 d4051202 00000005 Bitmap 00000040 00000000
00482060 fddd4008 00000ca4 00000000 39051206 00000005 Bitmap 00000040 00000000
00482170 fddb6008 00000ca4 00000000 20051217 00000005 Bitmap 00000040 00000000
00483140 ff4a0008 00000ca4 00000000 4e051314 00000005 Bitmap 00000040 00000000
00483870 ff427980 00000ca4 00000000 6d051387 00000005 Bitmap 00000040 00000000
00483d80 fe7d04b0 00000ca4 00000000 bd0513d8 00000005 Bitmap 00000040 00000000
00484620 ff437eb8 00000ca4 00000000 0d101462 00000010 Brush 00000040 000f0fd8
004846a0 fddc2da8 00000ca4 00000000 d305146a 00000005 Bitmap 00000040 00000000
00484b80 fdf1a728 00000ca4 00000000 530114b8 00000001 DC 00000040 000e0ae0
Gdi Handles for C:\Windows\system32\calc.exe
Total Gdi Handles = 21
DC = 2
Font = 0
Region = 17
Brush = 0
Bitmap = 1
Pen = 1
Pallete = 0
Unknpown = 0