[WIN32K]
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Sat, 19 Feb 2011 21:56:43 +0000 (21:56 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Sat, 19 Feb 2011 21:56:43 +0000 (21:56 +0000)
- 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

reactos/subsystems/win32/win32k/include/gdidebug.h
reactos/subsystems/win32/win32k/include/win32.h
reactos/subsystems/win32/win32k/objects/gdidbg.c

index 42c20f9..dc7179a 100644 (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
+
index 56bfd56..c6dc142 100644 (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>
index 3a0ac31..ab1a8d9 100644 (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++;
+                   DPRINT1("nDeleted=%ld\n", nDeleted);
+                   ASSERT(FALSE);
+               }
 
-                       /* 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");
-                       }
+        nDeleted++;
 
-                       i = (ULONG_PTR)pEntry->KernelData;
-                       if (!i)
-                       {
-                               break;
-                       }
-                       pEntry = &GdiHandleTable->Entries[i];
-               }
-       }
+        /* 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;
+}
+