[win32k]
authorGiannis Adamopoulos <gadamopoulos@reactos.org>
Sat, 27 Oct 2012 16:39:18 +0000 (16:39 +0000)
committerGiannis Adamopoulos <gadamopoulos@reactos.org>
Sat, 27 Oct 2012 16:39:18 +0000 (16:39 +0000)
- Fix WARN macros
- Keep a list of the PROCESSINFO of all the running processes
- Count how many handles a process owns per type in PROCESSINFO
- Improve the debug output when we run out of user handles to show all handle counts per process

svn path=/trunk/; revision=57623

reactos/win32ss/include/ntuser.h
reactos/win32ss/user/ntuser/main.c
reactos/win32ss/user/ntuser/ntuser.h
reactos/win32ss/user/ntuser/object.c
reactos/win32ss/user/ntuser/object.h
reactos/win32ss/user/ntuser/win32.h
reactos/win32ss/user/ntuser/win32kdebug.h

index b0f8732..3a0e963 100644 (file)
@@ -56,7 +56,8 @@ typedef enum _USER_OBJECT_TYPE
   otHidData,
   otDeviceInfo,
   otTouchInput,
-  otGestureInfo
+  otGestureInfo,
+  USER_HANDLE_TYPE_COUNT
 } USER_OBJECT_TYPE;
 
 typedef enum _USERTHREADINFOCLASS
index 6b9a5ed..92217d6 100644 (file)
@@ -26,6 +26,7 @@ PSERVERINFO gpsi = NULL; // Global User Server Information.
 
 SHORT gusLanguageID;
 PPROCESSINFO ppiScrnSaver;
+PPROCESSINFO gppiList = NULL;
 
 extern ULONG_PTR Win32kSSDT[];
 extern UCHAR Win32kSSPT[];
@@ -55,7 +56,7 @@ APIENTRY
 Win32kProcessCallback(struct _EPROCESS *Process,
                       BOOLEAN Create)
 {
-    PPROCESSINFO ppiCurrent;
+    PPROCESSINFO ppiCurrent, *pppi;
     DECLARE_RETURN(NTSTATUS);
 
     ASSERT(Process->Peb);
@@ -160,6 +161,10 @@ Win32kProcessCallback(struct _EPROCESS *Process,
         ASSERT(ppiCurrent->pPoolDcAttr);
         ASSERT(ppiCurrent->pPoolBrushAttr);
         ASSERT(ppiCurrent->pPoolRgnAttr);
+
+        /* Add the process to the global list */
+        ppiCurrent->ppiNext = gppiList;
+        gppiList = ppiCurrent;
     }
     else
     {
@@ -212,11 +217,25 @@ Win32kProcessCallback(struct _EPROCESS *Process,
 
         if (gppiInputProvider == ppiCurrent) gppiInputProvider = NULL;
 
+        pppi = &gppiList;
+        while (*pppi != NULL && *pppi != ppiCurrent)
+            pppi = &(*pppi)->ppiNext;
+
+        ASSERT(*pppi == ppiCurrent);
+
+        *pppi = ppiCurrent->ppiNext;
+
         TRACE_CH(UserProcess,"Freeing ppi 0x%p\n", ppiCurrent);
 
         /* Ftee the PROCESSINFO */
         PsSetProcessWin32Process(Process, NULL);
         ExFreePoolWithTag(ppiCurrent, USERTAG_PROCESSINFO);
+#if DBG
+        if (DBG_IS_CHANNEL_ENABLED(ppiCurrent, DbgChUserObj, WARN_LEVEL))
+        {
+            DbgUserDumpHandleTable();
+        }
+#endif
     }
 
     RETURN( STATUS_SUCCESS);
index b45a2d0..aab3ba3 100644 (file)
@@ -12,6 +12,7 @@
 extern BOOL gbInitialized;
 extern PSERVERINFO gpsi;
 extern PTHREADINFO gptiCurrent;
+extern PPROCESSINFO gppiList;
 extern PPROCESSINFO ppiScrnSaver;
 extern PPROCESSINFO gppiInputProvider;
 
index fdb318d..8117363 100644 (file)
@@ -12,6 +12,66 @@ DBG_DEFAULT_CHANNEL(UserObj);
 //int usedHandles=0;
 PUSER_HANDLE_TABLE gHandleTable = NULL;
 
+#if DBG
+
+void DbgUserDumpHandleTable()
+{
+    int HandleCounts[USER_HANDLE_TYPE_COUNT];
+    PPROCESSINFO ppiList;
+    int i;
+    PWCHAR TypeNames[] = {L"Free",L"Window",L"Menu", L"CursorIcon", L"SMWP", L"Hook", L"ClipBoardData", L"CallProc",
+                          L"Accel", L"DDEaccess", L"DDEconv", L"DDExact", L"Monitor", L"KBDlayout", L"KBDfile",
+                          L"Event", L"Timer", L"InputContext", L"HidData", L"DeviceInfo", L"TouchInput",L"GestureInfo"};
+
+    ERR("Total handles count: %d\n", gpsi->cHandleEntries);
+
+    memset(HandleCounts, 0, sizeof(HandleCounts));
+
+    /* First of all count the number of handles per tpe */
+    ppiList = gppiList;
+    while (ppiList)
+    {
+        ERR("Process %s (%d) handles count: %d\n\t", ppiList->peProcess->ImageFileName, ppiList->peProcess->UniqueProcessId, ppiList->UserHandleCount);
+
+        for (i = 1 ;i < USER_HANDLE_TYPE_COUNT; i++)
+        {
+            HandleCounts[i] += ppiList->DbgHandleCount[i];
+
+            DbgPrint("%S: %d, ", TypeNames[i], ppiList->DbgHandleCount[i]);
+            if (i % 6 == 0)
+                DbgPrint("\n\t");
+        }
+        DbgPrint("\n");
+
+        ppiList = ppiList->ppiNext;
+    }
+
+    /* Print total type counts */
+    ERR("Total handles of the running processes: \n\t");
+    for (i = 1 ;i < USER_HANDLE_TYPE_COUNT; i++)
+    {
+        DbgPrint("%S: %d, ", TypeNames[i], HandleCounts[i]);
+        if (i % 6 == 0)
+            DbgPrint("\n\t");
+    }
+    DbgPrint("\n");
+
+    /* Now count the handle counts that are allocated from the handle table */
+    memset(HandleCounts, 0, sizeof(HandleCounts));
+    for (i = 0; i < gHandleTable->nb_handles; i++)
+         HandleCounts[gHandleTable->handles[i].type]++;
+
+    ERR("Total handles count allocated: \n\t");
+    for (i = 1 ;i < USER_HANDLE_TYPE_COUNT; i++)
+    {
+        DbgPrint("%S: %d, ", TypeNames[i], HandleCounts[i]);
+        if (i % 6 == 0)
+            DbgPrint("\n\t");
+    }
+    DbgPrint("\n");
+}
+
+#endif
 
 PUSER_HANDLE_ENTRY handle_to_entry(PUSER_HANDLE_TABLE ht, HANDLE handle )
 {
@@ -51,55 +111,12 @@ __inline static PUSER_HANDLE_ENTRY alloc_user_entry(PUSER_HANDLE_TABLE ht)
 
    if (ht->nb_handles >= ht->allocated_handles)  /* Need to grow the array */
    {
-/**/
-      int i, iFree = 0, iWindow = 0, iMenu = 0, iCursorIcon = 0,
-          iHook = 0, iCallProc = 0, iAccel = 0, iMonitor = 0, iTimer = 0, iEvent = 0, iSMWP = 0;
- /**/
-      ERR("Out of user handles! Used -> %i, NM_Handle -> %d\n", gpsi->cHandleEntries, ht->nb_handles);
-//#if 0
-      for(i = 0; i < ht->nb_handles; i++)
-      {
-         switch (ht->handles[i].type)
-         {
-           case otFree: // Should be zero.
-            iFree++;
-            break;
-           case otWindow:
-            iWindow++;
-            break;
-           case otMenu:
-            iMenu++;
-            break;
-           case otCursorIcon:
-            iCursorIcon++;
-            break;
-           case otHook:
-            iHook++;
-            break;
-           case otCallProc:
-            iCallProc++;
-            break;
-           case otAccel:
-            iAccel++;
-            break;
-           case otMonitor:
-            iMonitor++;
-            break;
-           case otTimer:
-            iTimer++;
-            break;
-           case otEvent:
-            iEvent++;
-            break;
-           case otSMWP:
-            iSMWP++;
-           default:
-            break;
-         }
-      }
-      ERR("Handle Count by Type:\n Free = %d Window = %d Menu = %d CursorIcon = %d Hook = %d\n CallProc = %d Accel = %d Monitor = %d Timer = %d Event = %d SMWP = %d\n",
-      iFree, iWindow, iMenu, iCursorIcon, iHook, iCallProc, iAccel, iMonitor, iTimer, iEvent, iSMWP );
-//#endif
+       ERR("Out of user handles! Used -> %i, NM_Handle -> %d\n", gpsi->cHandleEntries, ht->nb_handles);
+
+#if DBG
+       DbgUserDumpHandleTable();
+#endif
+
       return NULL;
 #if 0
       PUSER_HANDLE_ENTRY new_handles;
@@ -138,6 +155,11 @@ __inline static void *free_user_entry(PUSER_HANDLE_TABLE ht, PUSER_HANDLE_ENTRY
 {
    PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
    void *ret;
+
+#if DBG
+   ppi->DbgHandleCount[entry->type]--;
+#endif
+
    ret = entry->ptr;
    entry->ptr  = ht->freelist;
    entry->type = 0;
@@ -339,6 +361,10 @@ UserCreateObject( PUSER_HANDLE_TABLE ht,
       return NULL;
    }
 
+#if DBG
+   ppi->DbgHandleCount[type]++;
+#endif
+
    RtlZeroMemory(Object, size);
 
    switch (type)
index eabc655..cad7ce2 100644 (file)
@@ -39,6 +39,7 @@ PVOID UserGetObject(PUSER_HANDLE_TABLE ht, HANDLE handle, USER_OBJECT_TYPE type
 PVOID UserGetObjectNoErr(PUSER_HANDLE_TABLE, HANDLE, USER_OBJECT_TYPE);
 BOOL FASTCALL UserCreateHandleTable(VOID);
 BOOL FASTCALL UserObjectInDestroy(HANDLE);
+void DbgUserDumpHandleTable();
 
 static __inline VOID
 UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
index a6290e6..4bec70a 100644 (file)
@@ -195,6 +195,7 @@ typedef struct _PROCESSINFO
   PTHREADINFO ptiList;
   PTHREADINFO ptiMainThread;
   struct _DESKTOP* rpdeskStartup;
+  PPROCESSINFO ppiNext;
   PCLS pclsPrivateList;
   PCLS pclsPublicList;
   INT cThreads;
@@ -224,6 +225,7 @@ typedef struct _PROCESSINFO
 
 #if DBG
   BYTE DbgChannelLevel[DbgChCount];
+  DWORD DbgHandleCount[USER_HANDLE_TYPE_COUNT];
 #endif
 } PROCESSINFO;
 
index 83de71a..d26c4c1 100644 (file)
 
     #define DBG_ENABLE_CHANNEL(ppi,ch,level) ((ppi)->DbgChannelLevel[ch] |= level)
     #define DBG_DISABLE_CHANNEL(ppi,ch,level) ((ppi)->DbgChannelLevel[ch] &= ~level)
-    #define DBG_IS_CHANNEL_ENABLED(ppi,ch,level) ((ppi)->DbgChannelLevel[ch] & level)
+    #define DBG_IS_CHANNEL_ENABLED(ppi,ch,level) (((ppi)->DbgChannelLevel[ch] & level) == level)
 
     #define DBG_PRINT(ppi,ch,level,fmt, ...)  do {                            \
     if((level == ERR_LEVEL) || (ppi && DBG_IS_CHANNEL_ENABLED(ppi,ch,level))) \