mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 21:32:56 +00:00
much improved reporting on gdi handle leaks ( you must completely run out of handles tho - which is rare now that quotas are implemented )
svn path=/trunk/; revision=12217
This commit is contained in:
parent
4a371112ec
commit
b27cf5b226
1 changed files with 51 additions and 36 deletions
|
@ -19,7 +19,7 @@
|
||||||
/*
|
/*
|
||||||
* GDIOBJ.C - GDI object manipulation routines
|
* GDIOBJ.C - GDI object manipulation routines
|
||||||
*
|
*
|
||||||
* $Id: gdiobj.c,v 1.80 2004/12/19 00:03:56 royce Exp $
|
* $Id: gdiobj.c,v 1.81 2004/12/19 05:03:29 royce Exp $
|
||||||
*/
|
*/
|
||||||
#include <w32k.h>
|
#include <w32k.h>
|
||||||
|
|
||||||
|
@ -212,33 +212,55 @@ GetObjectSize(DWORD ObjectType)
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
|
|
||||||
static int leak_reported = 0;
|
static int leak_reported = 0;
|
||||||
#define GDI_STACK_LEVELS 4
|
#define GDI_STACK_LEVELS 12
|
||||||
static ULONG GDIHandleAllocator[GDI_STACK_LEVELS][GDI_HANDLE_COUNT];
|
static ULONG GDIHandleAllocator[GDI_HANDLE_COUNT][GDI_STACK_LEVELS];
|
||||||
struct DbgOpenGDIHandle
|
struct DbgOpenGDIHandle
|
||||||
{
|
{
|
||||||
ULONG loc;
|
ULONG idx;
|
||||||
int count;
|
int count;
|
||||||
};
|
};
|
||||||
#define H 1024
|
#define H 1024
|
||||||
static struct DbgOpenGDIHandle h[H];
|
static struct DbgOpenGDIHandle h[H];
|
||||||
|
|
||||||
void IntDumpHandleTable ( int which )
|
void IntDumpHandleTable()
|
||||||
{
|
{
|
||||||
int i, n = 0, j;
|
int i, n = 0, j, k, J;
|
||||||
|
|
||||||
|
if ( leak_reported )
|
||||||
|
{
|
||||||
|
DPRINT1("gdi handle abusers already reported!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
leak_reported = 1;
|
||||||
|
DPRINT1("reporting gdi handle abusers:\n");
|
||||||
|
|
||||||
/* step through GDI handle table and find out who our culprit is... */
|
/* step through GDI handle table and find out who our culprit is... */
|
||||||
for ( i = RESERVE_ENTRIES_COUNT; i < GDI_HANDLE_COUNT; i++ )
|
for ( i = RESERVE_ENTRIES_COUNT; i < GDI_HANDLE_COUNT; i++ )
|
||||||
{
|
{
|
||||||
for ( j = 0; j < n; j++ )
|
for ( j = 0; j < n; j++ )
|
||||||
{
|
{
|
||||||
if ( GDIHandleAllocator[which][i] == h[j].loc )
|
next:
|
||||||
break;
|
J = h[j].idx;
|
||||||
|
for ( k = 0; k < GDI_STACK_LEVELS; k++ )
|
||||||
|
{
|
||||||
|
if ( GDIHandleAllocator[i][k]
|
||||||
|
!= GDIHandleAllocator[J][k] )
|
||||||
|
{
|
||||||
|
if ( ++j == n )
|
||||||
|
goto done;
|
||||||
|
else
|
||||||
|
goto next;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
done:
|
||||||
if ( j < H )
|
if ( j < H )
|
||||||
{
|
{
|
||||||
if ( j == n )
|
if ( j == n )
|
||||||
{
|
{
|
||||||
h[j].loc = GDIHandleAllocator[which][i];
|
h[j].idx = i;
|
||||||
h[j].count = 1;
|
h[j].count = 1;
|
||||||
n = n + 1;
|
n = n + 1;
|
||||||
}
|
}
|
||||||
|
@ -252,25 +274,30 @@ void IntDumpHandleTable ( int which )
|
||||||
if ( h[i].count < h[i+1].count )
|
if ( h[i].count < h[i+1].count )
|
||||||
{
|
{
|
||||||
struct DbgOpenGDIHandle t;
|
struct DbgOpenGDIHandle t;
|
||||||
t.loc = h[i+1].loc;
|
t = h[i+1];
|
||||||
t.count = h[i+1].count;
|
h[i+1] = h[i];
|
||||||
h[i+1].loc = h[i].loc;
|
|
||||||
h[i+1].count = h[i].count;
|
|
||||||
j = i;
|
j = i;
|
||||||
while ( j > 0 && h[j-1].count < t.count )
|
while ( j > 0 && h[j-1].count < t.count )
|
||||||
j--;
|
j--;
|
||||||
h[j] = t;
|
h[j] = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* print the first 30 offenders... */
|
/* print the worst offenders... */
|
||||||
DbgPrint ( "Worst GDI Handle leak offenders - stack trace level %i (out of %i unique locations):\n", which, n );
|
DbgPrint ( "Worst GDI Handle leak offenders (out of %i unique locations):\n", n );
|
||||||
for ( i = 0; i < 30 && i < n; i++ )
|
for ( i = 0; i < n && h[i].count > 1; i++ )
|
||||||
{
|
{
|
||||||
DbgPrint ( "\t" );
|
int j;
|
||||||
if ( !KeRosPrintAddress ( (PVOID)h[i].loc ) )
|
DbgPrint ( " %i allocs: ", h[i].count );
|
||||||
DbgPrint ( "<%X>", h[i].loc );
|
for ( j = 0; j < GDI_STACK_LEVELS; j++ )
|
||||||
DbgPrint ( " (%i allocations)\n", h[i].count );
|
{
|
||||||
|
ULONG Addr = GDIHandleAllocator[h[i].idx][j];
|
||||||
|
if ( !KeRosPrintAddress ( (PVOID)Addr ) )
|
||||||
|
DbgPrint ( "<%X>", Addr );
|
||||||
}
|
}
|
||||||
|
DbgPrint ( "\n" );
|
||||||
|
}
|
||||||
|
if ( i < n && h[i].count == 1 )
|
||||||
|
DbgPrint ( "(list terminated - the remaining entries have 1 allocation only)\n" );
|
||||||
}
|
}
|
||||||
#endif /* DBG */
|
#endif /* DBG */
|
||||||
|
|
||||||
|
@ -377,14 +404,13 @@ LockHandle:
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
__asm mov [Frame], ebp
|
__asm mov [Frame], ebp
|
||||||
#endif
|
#endif
|
||||||
Frame = (PULONG)Frame[0]; /* step out of AllocObj() */
|
|
||||||
for ( which = 0; which < GDI_STACK_LEVELS && Frame[1] != 0 && Frame[1] != 0xDEADBEEF; which++ )
|
for ( which = 0; which < GDI_STACK_LEVELS && Frame[1] != 0 && Frame[1] != 0xDEADBEEF; which++ )
|
||||||
{
|
{
|
||||||
GDIHandleAllocator[which][Index] = Frame[1]; /* step out of AllocObj() */
|
GDIHandleAllocator[Index][which] = Frame[1];
|
||||||
Frame = ((PULONG)Frame[0]);
|
Frame = ((PULONG)Frame[0]);
|
||||||
}
|
}
|
||||||
for ( ; which < GDI_STACK_LEVELS; which++ )
|
for ( ; which < GDI_STACK_LEVELS; which++ )
|
||||||
GDIHandleAllocator[which][Index] = 0xDEADBEEF;
|
GDIHandleAllocator[Index][which] = 0xDEADBEEF;
|
||||||
}
|
}
|
||||||
#endif /* DBG */
|
#endif /* DBG */
|
||||||
|
|
||||||
|
@ -416,18 +442,7 @@ LockHandle:
|
||||||
ExFreeToPagedLookasideList(LookasideList, newObject);
|
ExFreeToPagedLookasideList(LookasideList, newObject);
|
||||||
DPRINT1("Failed to insert gdi object into the handle table, no handles left!\n");
|
DPRINT1("Failed to insert gdi object into the handle table, no handles left!\n");
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
if ( !leak_reported )
|
IntDumpHandleTable();
|
||||||
{
|
|
||||||
DPRINT1("reporting gdi handle abusers:\n");
|
|
||||||
int which;
|
|
||||||
for ( which = 0; which < GDI_STACK_LEVELS; which++ )
|
|
||||||
IntDumpHandleTable(which);
|
|
||||||
leak_reported = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINT1("gdi handle abusers already reported!\n");
|
|
||||||
}
|
|
||||||
#endif /* DBG */
|
#endif /* DBG */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue