From dc29559c25924f269b2a24ff5c64c9ff8f3d264b Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sat, 19 Feb 2011 21:56:43 +0000 Subject: [PATCH] [WIN32K] - 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 --- .../win32/win32k/include/gdidebug.h | 38 +++++++ .../subsystems/win32/win32k/include/win32.h | 11 +- .../subsystems/win32/win32k/objects/gdidbg.c | 103 +++++++++++------- 3 files changed, 109 insertions(+), 43 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/gdidebug.h b/reactos/subsystems/win32/win32k/include/gdidebug.h index 42c20f97c82..dc7179ae24f 100644 --- a/reactos/subsystems/win32/win32k/include/gdidebug.h +++ b/reactos/subsystems/win32/win32k/include/gdidebug.h @@ -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 + diff --git a/reactos/subsystems/win32/win32k/include/win32.h b/reactos/subsystems/win32/win32k/include/win32.h index 56bfd56856a..c6dc142f2d3 100644 --- a/reactos/subsystems/win32/win32k/include/win32.h +++ b/reactos/subsystems/win32/win32k/include/win32.h @@ -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 diff --git a/reactos/subsystems/win32/win32k/objects/gdidbg.c b/reactos/subsystems/win32/win32k/objects/gdidbg.c index 3a0ac31600b..ab1a8d97f29 100644 --- a/reactos/subsystems/win32/win32k/objects/gdidbg.c +++ b/reactos/subsystems/win32/win32k/objects/gdidbg.c @@ -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; +} +