2009-10-26 3 views
2

덤프 충돌에서 GDI 핸들 수를 얻을 수 있습니다 내 프로세스가 추락했을 때 사용 했나요?명령은 내가 크래시 덤프를 가지고 내가 GDI 핸들의 수를 알아 어쨌든 전체 크래시 덤프에서 충돌</p> <p>의 원인으로 GDI 누수가 의심

+1

'! handles'은 덤프에있는 모든 핸들을 나열 할 것이지만 GDI를 포함하지 않는다고 생각합니다. http://msdn.microsoft.com/en-us/library/ms724211(VS) .85) .aspx. –

답변

2

g2i 버전 이후로 gdi 작업에 맞게 조정 된 유일한 디버거 확장 gdikdx.dll이 적극적으로 유지 관리되지 않기 때문에 가능성이 희박합니다. 많은 사람들이 gdi 내부 구조를 해킹하려고 시도한 것이 아니기 때문에 출하를 중단했다고 믿습니다. 나는 뉴스 그룹에서 우연히 만났습니다. 따라서 더 이상 투자되지 않습니다. 불행히도 런타임 문제 해결에 대한 몇 가지 옵션 만 남았습니다.

당신은 당신의 응용 프로그램에서 GDI 리소스의 사용을 모니터링하고 런타임 계측 옵션 중 하나를 진행 nirsoft의 GDIView 같은 도구를 시작할 수 :

추신 당신은 당신의 특별한 충돌의 실제 이유에 대해 좀 더 구체적 일 수 있습니까? 테스는 비슷한 상황에 대해 이야기

2

... 당신에게 리드를 줄 것이다 나는 모든 GDI는 GDI 핸들 테이블에서 처리 덤프하는 Windbg에서 스크립트를 만들었습니다. https://aloiskraus.wordpress.com/2016/06/25/show-gdi-handles-by-type-in-windbg/

예를 들어. 당신이 무엇을 볼 수있는이 시간이 변경되었습니다 여기에

0:013> $$>a<"D:\GdiDump\DumpGdi.txt" 
GDI Handle Table 00000000013e0000 0000000001561000 
GDI Handle Count  14 
    DeviceContexts: 4 
    Regions:  2 
    Bitmaps:  2 
    Palettes:  0 
    Fonts:   3 
    Brushes:  3 
    Pens:   0 
    Uncategorized: 0 
0:013> g 
0:014> $$>a<"D:\GdiDump\DumpGdi.txt" 
GDI Handle Table 00000000013e0000 0000000001561000 
GDI Handle Count  1021 
    DeviceContexts: 8 
    Regions:  3 
    Bitmaps:  1003 
    Palettes:  0 
    Fonts:   3 
    Brushes:  4 
    Pens:   0 
    Uncategorized: 0 

는 GDI를 덤프 대안 스크립트가 GdiSharedHandleTable에서이 라이브 사용자 모드/라이브 kernelmode에서 사용할 수있는 핸들되는 스크립트 여기

$$ Run as: $$>a<DumpGdi.txt 
$$ Written by Alois Kraus 2016 
$$ uses pseudo registers r0-5 and r8-r14 

r @$t1=0 
r @$t8=0 
r @$t9=0 
r @$t10=0 
r @$t11=0 
r @$t12=0 
r @$t13=0 
r @$t14=0 
$$ Increment count is 1 byte until we find a matching field with the current pid 
r @$t4=1 

r @$t0=$peb 
$$ Get address of GDI handle table into t5 
.foreach /pS 3 /ps 1 (@$GdiSharedHandleTable { dt ntdll!_PEB GdiSharedHandleTable @$t0 }) { r @$t5 = @$GdiSharedHandleTable } 

$$ On first call !address produces more output. Do a warmup 
.foreach /pS 50 (@$myStartAddress {!address @$t5}) { } 


$$ Get start address of file mapping into t2 
.foreach /pS 4 /ps 40 (@$myStartAddress {!address @$t5}) { r @$t2 = @$myStartAddress } 
$$ Get end address of file mapping into t3 
.foreach /pS 7 /ps 40 (@$myEndAddress {!address @$t5}) { r @$t3 = @$myEndAddress } 
.printf "GDI Handle Table %p %p", @$t2, @$t3 

.for(; @$t2 < @$t3; r @$t2 = @$t2 + @$t4) 
{ 
    $$ since we walk bytewise through potentially invalid memory we need first to check if it points to valid memory 
    .if($vvalid(@$t2,4) == 1) 
    { 
    $$ Check if pid matches 
    .if (wo(@$t2) == @$tpid) 
    { 
     $$ increase handle count stored in $t1 and increase step size by 0x18 because we know the cell structure GDICell has a size of 0x18 bytes. 
     r @$t1 = @$t1+1 
     r @$t4 = 0x18 
     $$ Access wType of GDICELL and increment per GDI handle type 
     .if (by(@$t2+6) == 0x1) { r @$t8 = @$t8+1 } 
     .if (by(@$t2+6) == 0x4) { r @$t9 = @$t9+1 } 
     .if (by(@$t2+6) == 0x5) { r @$t10 = @$t10+1 } 
     .if (by(@$t2+6) == 0x8) { r @$t11 = @$t11+1 } 
     .if (by(@$t2+6) == 0xa) { r @$t12 = @$t12+1 } 
     .if (by(@$t2+6) == 0x10) { r @$t13 = @$t13+1 } 
     .if (by(@$t2+6) == 0x30) { r @$t14 = @$t14+1 } 
    } 
    } 
} 

.printf "\nGDI Handle Count  %d", @$t1 
.printf "\n\tDeviceContexts: %d", @$t8 
.printf "\n\tRegions:  %d", @$t9 
.printf "\n\tBitmaps:  %d", @$t10 
.printf "\n\tPalettes:  %d", @$t11 
.printf "\n\tFonts:   %d", @$t12 
.printf "\n\tBrushes:  %d", @$t13 
.printf "\n\tPens:   %d", @$t14 
.printf "\n\tUncategorized: %d\n", @$t1-(@[email protected][email protected][email protected][email protected][email protected][email protected]$t8) 
+0

안녕하세요. http://stackoverflow.com/questions/40920898/do-i-need-a-wow64-dump-for-gd-handle-analysis를 살펴 보시겠습니까? WOW64 크래시 덤프의 필요성에 대한 후속 조치입니다. 감사. –

0

입니다/그것은 또한 사용할 수 있습니다 모드를 덤프! for_each_process 명령 문자열을 GDI는 커널 모드 디버깅에서 실행중인 모든 프로세스에서 처리 덤프

그것이 .catch 블록을 사용

는 KD에 요약 를 인쇄 GdiSharedhandleTable 페이지가 페이징되고 할당 크기보다 작게 잘립니다. peb 헤더가 페이징 됨 등 문제가 발생할 수 있습니다.
이 스크립트는 가능한 한 많이 읽으려고 시도하며 메모리 액세스 위반이 발생하면 catch 블록을 벗어납니다. 및 실행의 필요

r $t19=0;r $t18=0;r $t17=0;r $t16=0;r $t15=0;r $t14=0;r $t13=0;r $t12=0; 
r $t0 = @@c++(@$Peb->GdiSharedHandleTable) 
r $t1 = (@@c++(@$Peb->GdiSharedHandleTable) + 0xffffff) 
r $t2 = 0 
.catch { 
    .printf /D "<b>gdioffs Kaddr Pid  Count Handle Type Tname 
IsLive UAddr </b>\n"; 
    .while(@$t0 < @$t1) { 
    .while(wo(@$t0+4) != @$tpid) { 
     r $t0 = @$t0+0x10 ; r $t2 = @$t2+1  
    } 
    .printf "%08x " , @$t0 ; .printf "%08x " , dwo(@$t0) 
    .printf "%08x " , wo(@$t0+4) ;.printf "%08x " , wo(@$t0+6) 
    .printf "%08x " , (wo(@$t0+8)<<0x10)[email protected]$t2 ; .printf "%08x " , by(@$t0+a) 
    .if( by(@$t0+a) == 1) {r [email protected]$t19+1;.printf "DC  "} 
    .elsif( by(@$t0+a) == 4) {r [email protected]$t18+1;.printf "Region "} 
    .elsif( by(@$t0+a) == 5) {r [email protected]$t17+1;.printf "Bitmap "} 
    .elsif( by(@$t0+a) == 8) {r [email protected]$t16+1;.printf "Pallete "} 
    .elsif( by(@$t0+a) == a) {r [email protected]$t15+1;.printf "Font  "} 
    .elsif( by(@$t0+a) == 10) {r [email protected]$t14+1;.printf "Brush "} 
    .elsif( by(@$t0+a) == 30) {r [email protected]$t13+1;.printf "Pen  "} 
    .else      {r [email protected]$t12+1;.printf "Unknown "} 
    .printf "%08x " , by(@$t0+b) 
    .printf "%08x\n" , dwo(@$t0+c) 
    r $t0 = @$t0+0x10 
    r $t2 = @$t2+1 
    } 
} 
r? @$t11 = @@c++(@$peb->ProcessParameters->ImagePathName.Buffer) 
.printf /D "<b>Gdi Handles for %mu</b>\n", @$t11 
.printf "Total Gdi Handles = %d\n", (@[email protected][email protected][email protected][email protected][email protected][email protected][email protected]$t12) 
.printf "DC  = %d\n" , @$t19 ; .printf "Font  = %d\n" , @$t18 
.printf "Region = %d\n" , @$t17 ; .printf "Brush = %d\n" , @$t16 
.printf "Bitmap = %d\n" , @$t15 ; .printf "Pen  = %d\n" , @$t14 
.printf "Pallete = %d\n" , @$t13 ; .printf "Unknpown = %d\n" , @$t12 

결과로 조정하는 것이 BTW이 스크립트는 의사 레지스터 필요한 64 비트 32 비트입니다

을 회수 할 수 있었는지 의 요약을 인쇄

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 
Memory access error at ') != @$tpid) <-------- jumps out of catch block here 
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