fix checks for deleted gdi objects and add GDI_DEBUG function to trace the deleter of an object.

svn path=/trunk/; revision=33843
This commit is contained in:
Timo Kreuzer
2008-06-03 23:56:09 +00:00
parent 7c21c02f9b
commit 7bc03a5188
2 changed files with 24 additions and 13 deletions
@@ -7,6 +7,7 @@ static int leak_reported = 0;
#define GDI_STACK_LEVELS 12
static ULONG GDIHandleAllocator[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
static ULONG GDIHandleLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
static ULONG GDIHandleDeleter[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
struct DbgOpenGDIHandle
{
ULONG idx;
@@ -236,16 +237,21 @@ GdiDbgHTIntegrityCheck()
#define GDIDBG_TRACECALLER() \
DPRINT1("-> called from:\n"); \
KeRosDumpStackFrames(NULL, 20);
#define GDIDBG_TRACEALLOCATOR(index) \
#define GDIDBG_TRACEALLOCATOR(handle) \
DPRINT1("-> allocated from:\n"); \
KeRosDumpStackFrames(GDIHandleAllocator[index], GDI_STACK_LEVELS);
#define GDIDBG_TRACELOCKER(index) \
KeRosDumpStackFrames(GDIHandleAllocator[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
#define GDIDBG_TRACELOCKER(handle) \
DPRINT1("-> locked from:\n"); \
KeRosDumpStackFrames(GDIHandleLocker[index], GDI_STACK_LEVELS);
#define GDIDBG_CAPTUREALLOCATOR(index) \
CaptureStackBackTace((PVOID*)GDIHandleAllocator[index], GDI_STACK_LEVELS);
#define GDIDBG_CAPTURELOCKER(index) \
CaptureStackBackTace((PVOID*)GDIHandleLocker[index], GDI_STACK_LEVELS);
KeRosDumpStackFrames(GDIHandleLocker[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
#define GDIDBG_TRACEDELETER(handle) \
DPRINT1("-> deleted from:\n"); \
KeRosDumpStackFrames(GDIHandleDeleter[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
#define GDIDBG_CAPTUREALLOCATOR(handle) \
CaptureStackBackTace((PVOID*)GDIHandleAllocator[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
#define GDIDBG_CAPTURELOCKER(handle) \
CaptureStackBackTace((PVOID*)GDIHandleLocker[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
#define GDIDBG_CAPTUREDELETER(handle) \
CaptureStackBackTace((PVOID*)GDIHandleDeleter[GDI_HANDLE_GET_INDEX(handle)], GDI_STACK_LEVELS);
#define GDIDBG_DUMPHANDLETABLE() \
IntDumpHandleTable(GdiHandleTable)
#define GDIDBG_INITLOOPTRACE() \
@@ -263,9 +269,11 @@ GdiDbgHTIntegrityCheck()
#define GDIDBG_TRACELOCKER(index)
#define GDIDBG_CAPTUREALLOCATOR(index)
#define GDIDBG_CAPTURELOCKER(index)
#define GDIDBG_CAPTUREDELETER(handle)
#define GDIDBG_DUMPHANDLETABLE()
#define GDIDBG_INITLOOPTRACE()
#define GDIDBG_TRACELOOP(Handle, PrevThread, Thread)
#define GDIDBG_TRACEDELETER(handle)
#endif /* GDI_DEBUG */
@@ -171,6 +171,7 @@ LockErrorDebugOutput(HGDIOBJ hObj, PGDI_TABLE_ENTRY Entry, LPSTR Function)
if ((Entry->Type & GDI_ENTRY_BASETYPE_MASK) == 0)
{
DPRINT1("%s: Attempted to lock object 0x%x that is deleted!\n", Function, hObj);
GDIDBG_TRACEDELETER(hObj);
}
else if (GDI_HANDLE_GET_REUSECNT(hObj) != GDI_ENTRY_GET_REUSECNT(Entry->Type))
{
@@ -527,6 +528,7 @@ LockHandle:
/* Now it's time to free the memory */
GDIOBJ_FreeObj(Object, TypeIndex);
GDIDBG_CAPTUREDELETER(hObj);
return Ret;
}
else
@@ -589,7 +591,7 @@ IsObjectDead(HGDIOBJ hObject)
INT Index = GDI_HANDLE_GET_INDEX(hObject);
PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
// We check to see if the objects are knocking on deaths door.
if ((Entry->Type & ~GDI_ENTRY_REUSE_MASK) != 0 && Entry->KernelData != NULL)
if ((Entry->Type & GDI_ENTRY_BASETYPE_MASK) != 0)
return FALSE;
else
{
@@ -747,7 +749,8 @@ GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ExpectedType)
DPRINT1("Attempted to lock object 0x%x of wrong type (Handle: 0x%x, requested: 0x%x)\n",
hObj, HandleType, ExpectedType);
GDIDBG_TRACECALLER();
GDIDBG_TRACEALLOCATOR(GDI_HANDLE_GET_INDEX(hObj));
GDIDBG_TRACEALLOCATOR(hObj);
GDIDBG_TRACEDELETER(hObj);
return NULL;
}
@@ -1009,7 +1012,7 @@ GDIOBJ_OwnedByCurrentProcess(HGDIOBJ ObjectHandle)
Entry = GDI_HANDLE_GET_ENTRY(GdiHandleTable, ObjectHandle);
Ret = Entry->KernelData != NULL &&
(Entry->Type & ~GDI_ENTRY_REUSE_MASK) != 0 &&
(Entry->Type & GDI_ENTRY_BASETYPE_MASK) != 0 &&
(HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1) == ProcessId;
return Ret;
@@ -1179,7 +1182,7 @@ LockHandle:
{
PW32THREAD PrevThread;
if ((Entry->Type & ~GDI_ENTRY_REUSE_MASK) != 0 && Entry->KernelData != NULL)
if ((Entry->Type & GDI_ENTRY_BASETYPE_MASK) != 0)
{
POBJ Object = Entry->KernelData;
@@ -1309,7 +1312,7 @@ LockHandleFrom:
PW32THREAD PrevThread;
POBJ Object;
if ((FromEntry->Type & ~GDI_ENTRY_REUSE_MASK) != 0 && FromEntry->KernelData != NULL)
if ((FromEntry->Type & GDI_ENTRY_BASETYPE_MASK) != 0)
{
Object = FromEntry->KernelData;