- Add ros specific member cExclusiveLocks to THREADINFO to track number of acquired locks
- Add functions/macros to check lock count
- Move some definitions into gdidebug.h for global use
- Fix broken GdiDbgHTIntegrityCheck
- Add pre and post syscall hook functions (unused yet)

svn path=/trunk/; revision=50824
This commit is contained in:
Timo Kreuzer 2011-02-19 21:56:43 +00:00
parent ea5522e1d8
commit dc29559c25
3 changed files with 109 additions and 43 deletions

View file

@ -2,6 +2,12 @@
extern ULONG gulDebugChannels;
#define GDI_STACK_LEVELS 20
extern ULONG_PTR GDIHandleAllocator[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
extern ULONG_PTR GDIHandleLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
extern ULONG_PTR GDIHandleShareLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
extern ULONG_PTR GDIHandleDeleter[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
enum _DEBUGCHANNELS
{
DbgCustom = 1,
@ -11,6 +17,10 @@ enum _DEBUGCHANNELS
DbgModeSwitch = 16,
};
void IntDumpHandleTable(PGDI_HANDLE_TABLE HandleTable);
ULONG CaptureStackBackTace(PVOID* pFrames, ULONG nFramesToCapture);
BOOL GdiDbgHTIntegrityCheck();
#define DBGENABLE(ch) gulDebugChannels |= (ch);
#define DBGDISABLE(ch) gulDebugChannels &= ~(ch);
#define DPRINTCH(ch) if (gulDebugChannels & (ch)) DbgPrint
@ -73,3 +83,31 @@ NTSYSAPI ULONG APIENTRY RtlWalkFrameChain(OUT PVOID *Callers, IN ULONG Count, IN
#endif /* GDI_DEBUG */
#if DBG
void
NTAPI
DbgPreServiceHook(ULONG ulSyscallId, PULONG_PTR pulArguments);
ULONG_PTR
NTAPI
DbgPostServiceHook(ULONG ulSyscallId, ULONG_PTR ulResult);
#define ID_Win32PreServiceHook 'WSH0'
#define ID_Win32PostServiceHook 'WSH1'
FORCEINLINE void
DbgAssertNoGdiLocks(char * pszFile, ULONG nLine)
{
PTHREADINFO pti = (PTHREADINFO)PsGetCurrentThreadWin32Thread();
if (pti && pti->cExclusiveLocks != 0)
{
DbgPrint("(%s:%ld) There are %ld exclusive locks!\n",
pszFile, nLine, pti->cExclusiveLocks);
ASSERT(FALSE);
}
}
#define ASSERT_NOGDILOCKS() DbgAssertNoGdiLocks(__FILE__,__LINE__)
#else
#define ASSERT_NOGDILOCKS()
#endif

View file

@ -99,10 +99,13 @@ typedef struct _THREADINFO
LIST_ENTRY aphkStart[NB_HOOKS];
CLIENTTHREADINFO cti; // Used only when no Desktop or pcti NULL.
/* ReactOS */
LIST_ENTRY WindowListHead;
LIST_ENTRY W32CallbackListHead;
SINGLE_LIST_ENTRY ReferencesList;
/* ReactOS */
LIST_ENTRY WindowListHead;
LIST_ENTRY W32CallbackListHead;
SINGLE_LIST_ENTRY ReferencesList;
ULONG cExclusiveLocks;
} THREADINFO;
#include <poppack.h>

View file

@ -17,11 +17,10 @@ ULONG gulDebugChannels = 0;
#ifdef GDI_DEBUG
#define GDI_STACK_LEVELS 20
static ULONG_PTR GDIHandleAllocator[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
static ULONG_PTR GDIHandleLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
static ULONG_PTR GDIHandleShareLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
static ULONG_PTR GDIHandleDeleter[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
ULONG_PTR GDIHandleAllocator[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
ULONG_PTR GDIHandleLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
ULONG_PTR GDIHandleShareLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
ULONG_PTR GDIHandleDeleter[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
struct DbgOpenGDIHandle
{
ULONG idx;
@ -172,44 +171,42 @@ GdiDbgHTIntegrityCheck()
/* FIXME: check reserved entries */
/* Now go through the deleted objects */
i = GdiHandleTable->FirstFree;
if (i)
i = GdiHandleTable->FirstFree & 0xffff;
while (i)
{
pEntry = &GdiHandleTable->Entries[i];
for (;;)
if (i > GDI_HANDLE_COUNT)
{
nDeleted++;
/* Check the entry */
if ((pEntry->Type & GDI_ENTRY_BASETYPE_MASK) != 0)
{
r = 0;
DPRINT1("Deleted Entry has a type != 0\n");
}
if ((ULONG_PTR)pEntry->KernelData >= GDI_HANDLE_COUNT)
{
r = 0;
DPRINT1("Deleted entries KernelPointer too big\n");
}
if (pEntry->UserData != NULL)
{
r = 0;
DPRINT1("Deleted entry has UserData != 0\n");
}
if (pEntry->ProcessId != 0)
{
r = 0;
DPRINT1("Deleted entry has ProcessId != 0\n");
}
i = (ULONG_PTR)pEntry->KernelData;
if (!i)
{
break;
}
pEntry = &GdiHandleTable->Entries[i];
DPRINT1("nDeleted=%ld\n", nDeleted);
ASSERT(FALSE);
}
}
nDeleted++;
/* Check the entry */
if ((pEntry->Type & GDI_ENTRY_BASETYPE_MASK) != 0)
{
r = 0;
DPRINT1("Deleted Entry has a type != 0\n");
}
if ((ULONG_PTR)pEntry->KernelData >= GDI_HANDLE_COUNT)
{
r = 0;
DPRINT1("Deleted entries KernelPointer too big\n");
}
if (pEntry->UserData != NULL)
{
r = 0;
DPRINT1("Deleted entry has UserData != 0\n");
}
if (pEntry->ProcessId != 0)
{
r = 0;
DPRINT1("Deleted entry has ProcessId != 0\n");
}
i = (ULONG_PTR)pEntry->KernelData & 0xffff;
};
for (i = GdiHandleTable->FirstUnused;
i < GDI_HANDLE_COUNT;
@ -295,3 +292,31 @@ GDIOBJ_IncrementShareCount(POBJ Object)
#endif /* GDI_DEBUG */
void
NTAPI
DbgPreServiceHook(ULONG ulSyscallId, PULONG_PTR pulArguments)
{
PTHREADINFO pti = (PTHREADINFO)PsGetCurrentThreadWin32Thread();
if (pti && pti->cExclusiveLocks != 0)
{
DbgPrint("FATAL: Win32DbgPreServiceHook(%ld): There are %ld exclusive locks!\n",
ulSyscallId, pti->cExclusiveLocks);
ASSERT(FALSE);
}
}
ULONG_PTR
NTAPI
DbgPostServiceHook(ULONG ulSyscallId, ULONG_PTR ulResult)
{
PTHREADINFO pti = (PTHREADINFO)PsGetCurrentThreadWin32Thread();
if (pti && pti->cExclusiveLocks != 0)
{
DbgPrint("FATAL: Win32DbgPostServiceHook(%ld): There are %ld exclusive locks!\n",
ulSyscallId, pti->cExclusiveLocks);
ASSERT(FALSE);
}
return ulResult;
}