mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 13:21:39 +00:00
dump some statistics on the gdi handle table when it runs out of handles
svn path=/trunk/; revision=12206
This commit is contained in:
parent
de1d28fabc
commit
5016bfecf7
1 changed files with 133 additions and 29 deletions
|
@ -19,7 +19,7 @@
|
|||
/*
|
||||
* GDIOBJ.C - GDI object manipulation routines
|
||||
*
|
||||
* $Id: gdiobj.c,v 1.78 2004/12/17 15:12:37 navaraf Exp $
|
||||
* $Id: gdiobj.c,v 1.79 2004/12/18 21:41:17 royce Exp $
|
||||
*/
|
||||
#include <w32k.h>
|
||||
|
||||
|
@ -209,6 +209,71 @@ GetObjectSize(DWORD ObjectType)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DBG
|
||||
|
||||
static int leak_reported = 0;
|
||||
#define GDI_STACK_LEVELS 4
|
||||
static ULONG GDIHandleAllocator[GDI_STACK_LEVELS][GDI_HANDLE_COUNT];
|
||||
struct DbgOpenGDIHandle
|
||||
{
|
||||
ULONG loc;
|
||||
int count;
|
||||
};
|
||||
#define H 1024
|
||||
static struct DbgOpenGDIHandle h[H];
|
||||
|
||||
void IntDumpHandleTable ( int which )
|
||||
{
|
||||
int i, n = 0, j;
|
||||
|
||||
// step through GDI handle table and find out who our culprit is...
|
||||
for ( i = RESERVE_ENTRIES_COUNT; i < GDI_HANDLE_COUNT; i++ )
|
||||
{
|
||||
for ( j = 0; j < n; j++ )
|
||||
{
|
||||
if ( GDIHandleAllocator[which][i] == h[j].loc )
|
||||
break;
|
||||
}
|
||||
if ( j < H )
|
||||
{
|
||||
if ( j == n )
|
||||
{
|
||||
h[j].loc = GDIHandleAllocator[which][i];
|
||||
h[j].count = 1;
|
||||
n = n + 1;
|
||||
}
|
||||
else
|
||||
h[j].count++;
|
||||
}
|
||||
}
|
||||
// bubble sort time! weeeeee!!
|
||||
for ( i = 0; i < n-1; i++ )
|
||||
{
|
||||
if ( h[i].count < h[i+1].count )
|
||||
{
|
||||
struct DbgOpenGDIHandle t;
|
||||
t.loc = h[i+1].loc;
|
||||
t.count = h[i+1].count;
|
||||
h[i+1].loc = h[i].loc;
|
||||
h[i+1].count = h[i].count;
|
||||
j = i;
|
||||
while ( j > 0 && h[j-1].count < t.count )
|
||||
j--;
|
||||
h[j] = t;
|
||||
}
|
||||
}
|
||||
// print the first 30 offenders...
|
||||
DbgPrint ( "Worst GDI Handle leak offenders - stack trace level %i (out of %i unique locations):\n", which, n );
|
||||
for ( i = 0; i < 30 && i < n; i++ )
|
||||
{
|
||||
DbgPrint ( "\t" );
|
||||
if ( !KeRosPrintAddress ( (PVOID)h[i].loc ) )
|
||||
DbgPrint ( "<%X>", h[i].loc );
|
||||
DbgPrint ( " (%i allocations)\n", h[i].count );
|
||||
}
|
||||
}
|
||||
#endif//DBG
|
||||
|
||||
/*!
|
||||
* Allocate memory for GDI object and return handle to it.
|
||||
*
|
||||
|
@ -298,6 +363,27 @@ LockHandle:
|
|||
/* unlock the entry */
|
||||
InterlockedExchange(&Entry->ProcessId, CurrentProcessId);
|
||||
|
||||
#ifdef DBG
|
||||
{
|
||||
PULONG Frame;
|
||||
int which;
|
||||
#if defined __GNUC__
|
||||
__asm__("mov %%ebp, %%ebx" : "=b" (Frame) : );
|
||||
#elif defined(_MSC_VER)
|
||||
__asm mov [Frame], ebp
|
||||
#endif
|
||||
Frame = (PULONG)Frame[0]; // step out of AllocObj()
|
||||
for ( which = 0; which < GDI_STACK_LEVELS && Frame[1] != 0 && Frame[1] != 0xDEADBEEF; which++ )
|
||||
{
|
||||
GDIHandleAllocator[which][Index] = Frame[1]; // step out of AllocObj()
|
||||
Frame = ((PULONG)Frame[0]);
|
||||
}
|
||||
for ( ; which < GDI_STACK_LEVELS; which++ )
|
||||
GDIHandleAllocator[which][Index] = 0xDEADBEEF;
|
||||
}
|
||||
#endif//DBG
|
||||
//ExAllocatePool ( PagedPool, (ULONG)newObject ); // initiate red-zone verification of object we allocated
|
||||
|
||||
if(W32Process != NULL)
|
||||
{
|
||||
InterlockedIncrement(&W32Process->GDIObjects);
|
||||
|
@ -325,6 +411,20 @@ LockHandle:
|
|||
|
||||
ExFreeToPagedLookasideList(LookasideList, newObject);
|
||||
DPRINT1("Failed to insert gdi object into the handle table, no handles left!\n");
|
||||
#ifdef DBG
|
||||
if ( !leak_reported )
|
||||
{
|
||||
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
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -751,10 +851,12 @@ LockHandle:
|
|||
if(EntryType == 0)
|
||||
{
|
||||
DPRINT1("Attempted to lock object 0x%x that is deleted!\n", hObj);
|
||||
KeRosDumpStackFrames ( NULL, 20 );
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("Attempted to lock object 0x%x, type mismatch (0x%x : 0x%x)\n", hObj, EntryType, ExpectedType);
|
||||
KeRosDumpStackFrames ( NULL, 20 );
|
||||
}
|
||||
#ifdef GDI_DEBUG
|
||||
DPRINT1("-> called from %s:%i\n", file, line);
|
||||
|
@ -786,6 +888,7 @@ LockHandle:
|
|||
else
|
||||
{
|
||||
DPRINT1("Attempted to lock foreign handle: 0x%x, Owner: 0x%x locked: 0x%x Caller: 0x%x, stockobj: 0x%x\n", hObj, PrevProcId >> 1, PrevProcId & 0x1, PsGetCurrentProcessId(), GDI_HANDLE_IS_STOCKOBJ(hObj));
|
||||
KeRosDumpStackFrames ( NULL, 20 );
|
||||
#ifdef GDI_DEBUG
|
||||
DPRINT1("-> called from %s:%i\n", file, line);
|
||||
#endif
|
||||
|
@ -842,6 +945,7 @@ LockHandle:
|
|||
PGDIOBJHDR GdiHdr;
|
||||
|
||||
GdiHdr = GDIBdyToHdr(Entry->KernelData);
|
||||
//ExAllocatePool ( PagedPool, (ULONG)GdiHdr ); // initiate red-zone validation on this block
|
||||
|
||||
PrevThread = GdiHdr->LockingThread;
|
||||
if(PrevThread == Thread)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue