[ros-diffs] [tkreuzer] 32149: - use intrinsic interlocked functions - add a function to get a full stackbacktrace including usermode

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Wed Feb 6 06:09:26 CET 2008


Author: tkreuzer
Date: Wed Feb  6 08:09:26 2008
New Revision: 32149

URL: http://svn.reactos.org/svn/reactos?rev=32149&view=rev
Log:
- use intrinsic interlocked functions
- add a function to get a full stackbacktrace including usermode

Modified:
    trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c

Modified: trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c?rev=32149&r1=32148&r2=32149&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c Wed Feb  6 08:09:26 2008
@@ -32,6 +32,7 @@
 
 #ifdef GDI_DEBUG
 BOOLEAN STDCALL KiRosPrintAddress(PVOID Address);
+NTSYSAPI ULONG NTAPI RtlWalkFrameChain(OUT PVOID *Callers, IN ULONG Count, IN ULONG Flags);
 #endif
 
 #define GDI_ENTRY_TO_INDEX(ht, e)                                              \
@@ -170,7 +171,7 @@
   }
 
   ShortDelay.QuadPart = -5000LL; /* FIXME - 0.5 ms? */
-  
+
   HandleTable->FirstFree = 0;
   HandleTable->FirstUnused = RESERVE_ENTRIES_COUNT;
 
@@ -200,8 +201,8 @@
 
 static int leak_reported = 0;
 #define GDI_STACK_LEVELS 12
-static ULONG GDIHandleAllocator[GDI_HANDLE_COUNT][GDI_STACK_LEVELS];
-static ULONG GDIHandleLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS];
+static ULONG GDIHandleAllocator[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
+static ULONG GDIHandleLocker[GDI_HANDLE_COUNT][GDI_STACK_LEVELS+1];
 struct DbgOpenGDIHandle
 {
 	ULONG idx;
@@ -287,6 +288,23 @@
 	if ( i < n && h[i].count == 1 )
 		DbgPrint ( "(list terminated - the remaining entries have 1 allocation only)\n" );
 }
+
+ULONG
+CaptureStackBackTace(PVOID* pFrames, ULONG nFramesToCapture)
+{
+    ULONG nFrameCount;
+
+    memset(pFrames, 0x00, (nFramesToCapture + 1) * sizeof(PVOID));
+
+    nFrameCount = RtlCaptureStackBackTrace(1, nFramesToCapture, pFrames, NULL);
+
+    if (nFrameCount < nFramesToCapture)
+    {
+        nFrameCount += RtlWalkFrameChain(pFrames + nFrameCount, nFramesToCapture - nFrameCount, 1);
+    }
+
+    return nFrameCount;
+}
 #endif /* GDI_DEBUG */
 
 
@@ -334,7 +352,7 @@
 			idxNextFree = (ULONG)pFreeEntry->KernelData;
 			idxPrev = (ULONG)_InterlockedCompareExchange((LONG*)&HandleTable->FirstFree, idxNextFree, idxFirstFree);
 		}
-		else 
+		else
 		{
 			idxFirstFree = HandleTable->FirstUnused;
 			idxNextFree = idxFirstFree + 1;
@@ -470,7 +488,7 @@
       Entry = &HandleTable->Entries[Index];
 
 LockHandle:
-      PrevProcId = InterlockedCompareExchangePointer(&Entry->ProcessId, LockedProcessId, 0);
+      PrevProcId = _InterlockedCompareExchangePointer((PVOID*)&Entry->ProcessId, LockedProcessId, 0);
       if(PrevProcId == NULL)
       {
         HGDIOBJ Handle;
@@ -485,16 +503,15 @@
         Entry->Type = TypeInfo;
 
         /* unlock the entry */
-        (void)InterlockedExchangePointer(&Entry->ProcessId, CurrentProcessId);
-
-#ifdef GDI_DEBUG
-        memset ( GDIHandleAllocator[Index], 0x00, GDI_STACK_LEVELS * sizeof(ULONG) );
-        RtlCaptureStackBackTrace(1, GDI_STACK_LEVELS, (PVOID*)GDIHandleAllocator[Index], NULL);
+        (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, CurrentProcessId);
+
+#ifdef GDI_DEBUG
+        CaptureStackBackTace((PVOID*)GDIHandleAllocator[Index], GDI_STACK_LEVELS);
 #endif /* GDI_DEBUG */
 
         if(W32Process != NULL)
         {
-          InterlockedIncrement(&W32Process->GDIObjects);
+          _InterlockedIncrement(&W32Process->GDIObjects);
         }
         Handle = (HGDIOBJ)((Index & 0xFFFF) | (TypeInfo << GDI_ENTRY_UPPER_SHIFT));
 
@@ -586,8 +603,12 @@
         HandleType != ExpectedType) ||
        HandleType == 0 )
   {
-     DPRINT1("Attempted to free object 0x%x of wrong type (Handle: 0x%x, expected: 0x%x)\n",
-             hObj, HandleType, ExpectedType);
+    DPRINT1("Attempted to free object 0x%x of wrong type (Handle: 0x%x, expected: 0x%x)\n",
+            hObj, HandleType, ExpectedType);
+#ifdef GDI_DEBUG
+    DPRINT1("-> called from:\n");
+    KeRosDumpStackFrames(NULL, 20);
+#endif
      return FALSE;
   }
 
@@ -596,7 +617,7 @@
 LockHandle:
   /* lock the object, we must not delete global objects, so don't exchange the locking
      process ID to zero when attempting to lock a global object... */
-  PrevProcId = InterlockedCompareExchangePointer(&Entry->ProcessId, LockedProcessId, ProcessId);
+  PrevProcId = _InterlockedCompareExchangePointer((PVOID*)&Entry->ProcessId, LockedProcessId, ProcessId);
   if(PrevProcId == ProcessId)
   {
     if( (Entry->KernelData != NULL) &&
@@ -616,14 +637,14 @@
         Entry->Type = (Entry->Type + GDI_ENTRY_REUSE_INC) & ~GDI_ENTRY_BASETYPE_MASK;
 
         /* unlock the handle slot */
-        (void)InterlockedExchangePointer(&Entry->ProcessId, NULL);
+        (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, NULL);
 
         /* push this entry to the free list */
         InterlockedPushFreeEntry(HandleTable, GDI_ENTRY_TO_INDEX(HandleTable, Entry));
 
         if(W32Process != NULL)
         {
-          InterlockedDecrement(&W32Process->GDIObjects);
+          _InterlockedDecrement(&W32Process->GDIObjects);
         }
 
         /* call the cleanup routine. */
@@ -662,7 +683,7 @@
     else
     {
       LockErrorDebugOutput(hObj, Entry, "GDIOBJ_FreeObj");
-      (void)InterlockedExchangePointer(&Entry->ProcessId, PrevProcId);
+      (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, PrevProcId);
     }
   }
   else if(PrevProcId == LockedProcessId)
@@ -883,7 +904,7 @@
    {
       /* Lock the handle table entry. */
       LockedProcessId = (HANDLE)((ULONG_PTR)HandleProcessId | 0x1);
-      PrevProcId = InterlockedCompareExchangePointer(&Entry->ProcessId,
+      PrevProcId = _InterlockedCompareExchangePointer((PVOID*)&Entry->ProcessId,
                                                      LockedProcessId,
                                                      HandleProcessId);
 
@@ -905,20 +926,19 @@
                GdiHdr->LockingThread = Thread;
                GdiHdr->Locks = 1;
 #ifdef GDI_DEBUG
-               memset(GDIHandleLocker[GDI_HANDLE_GET_INDEX(hObj)], 0x00, GDI_STACK_LEVELS * sizeof(ULONG));
-               RtlCaptureStackBackTrace(1, GDI_STACK_LEVELS, (PVOID*)GDIHandleLocker[GDI_HANDLE_GET_INDEX(hObj)], NULL);
+               CaptureStackBackTace((PVOID*)GDIHandleLocker[GDI_HANDLE_GET_INDEX(hObj)], GDI_STACK_LEVELS);
 #endif
                Object = Entry->KernelData;
             }
             else
             {
-               InterlockedIncrement((PLONG)&GdiHdr->Locks);
+               _InterlockedIncrement((PLONG)&GdiHdr->Locks);
                if (GdiHdr->LockingThread != Thread)
                {
-                  InterlockedDecrement((PLONG)&GdiHdr->Locks);
+                  _InterlockedDecrement((PLONG)&GdiHdr->Locks);
 
                   /* Unlock the handle table entry. */
-                  (void)InterlockedExchangePointer(&Entry->ProcessId, PrevProcId);
+                  (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, PrevProcId);
 
                   DelayExecution();
                   continue;
@@ -941,7 +961,7 @@
          }
 
          /* Unlock the handle table entry. */
-         (void)InterlockedExchangePointer(&Entry->ProcessId, PrevProcId);
+         (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, PrevProcId);
 
          break;
       }
@@ -1028,7 +1048,7 @@
    {
       /* Lock the handle table entry. */
       LockedProcessId = (HANDLE)((ULONG_PTR)HandleProcessId | 0x1);
-      PrevProcId = InterlockedCompareExchangePointer(&Entry->ProcessId,
+      PrevProcId = _InterlockedCompareExchangePointer((PVOID*)&Entry->ProcessId,
                                                      LockedProcessId,
                                                      HandleProcessId);
 
@@ -1045,13 +1065,13 @@
             PGDIOBJHDR GdiHdr = GDIBdyToHdr(Entry->KernelData);
 
 #ifdef GDI_DEBUG
-            if (InterlockedIncrement((PLONG)&GdiHdr->Locks) == 1)
+            if (_InterlockedIncrement((PLONG)&GdiHdr->Locks) == 1)
             {
                  memset(GDIHandleLocker[HandleIndex], 0x00, GDI_STACK_LEVELS * sizeof(ULONG));
                  RtlCaptureStackBackTrace(1, GDI_STACK_LEVELS, (PVOID*)GDIHandleLocker[HandleIndex], NULL);
             }
 #else
-            InterlockedIncrement((PLONG)&GdiHdr->Locks);
+            _InterlockedIncrement((PLONG)&GdiHdr->Locks);
 #endif
             Object = Entry->KernelData;
          }
@@ -1070,7 +1090,7 @@
          }
 
          /* Unlock the handle table entry. */
-         (void)InterlockedExchangePointer(&Entry->ProcessId, PrevProcId);
+         (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, PrevProcId);
 
          break;
       }
@@ -1102,13 +1122,13 @@
 {
    PGDIOBJHDR GdiHdr = GDIBdyToHdr(Object);
 #ifdef GDI_DEBUG
-   if (InterlockedDecrement((PLONG)&GdiHdr->Locks) == 0)
+   if (_InterlockedDecrement((PLONG)&GdiHdr->Locks) == 0)
    {
         memset(GDIHandleLocker[GDI_HANDLE_GET_INDEX(Object)], 0x00, GDI_STACK_LEVELS * sizeof(ULONG));
         RtlCaptureStackBackTrace(1, GDI_STACK_LEVELS, (PVOID*)GDIHandleLocker[GDI_HANDLE_GET_INDEX(Object)], NULL);
    }
 #else
-   if (InterlockedDecrement((PLONG)&GdiHdr->Locks) < 0)
+   if (_InterlockedDecrement((PLONG)&GdiHdr->Locks) < 0)
        DPRINT1("Trying to unlock non-existant object\n");
 #endif
 }
@@ -1168,7 +1188,7 @@
 
 LockHandle:
     /* lock the object, we must not convert stock objects, so don't check!!! */
-    PrevProcId = InterlockedCompareExchangePointer(&Entry->ProcessId, LockedProcessId, ProcessId);
+    PrevProcId = _InterlockedCompareExchangePointer((PVOID*)&Entry->ProcessId, LockedProcessId, ProcessId);
     if(PrevProcId == ProcessId)
     {
       LONG NewType, PrevType, OldType;
@@ -1188,7 +1208,7 @@
       NewType = OldType | GDI_ENTRY_STOCK_MASK;
 
       /* Try to exchange the type field - but only if the old (previous type) matches! */
-      PrevType = InterlockedCompareExchange(&Entry->Type, NewType, OldType);
+      PrevType = _InterlockedCompareExchange(&Entry->Type, NewType, OldType);
       if(PrevType == OldType && Entry->KernelData != NULL)
       {
         PETHREAD PrevThread;
@@ -1217,14 +1237,14 @@
               W32Process = (PW32PROCESS)OldProcess->Win32Process;
               if(W32Process != NULL)
               {
-                InterlockedDecrement(&W32Process->GDIObjects);
+                _InterlockedDecrement(&W32Process->GDIObjects);
               }
               ObDereferenceObject(OldProcess);
             }
           }
 
           /* remove the process id lock and make it global */
-          (void)InterlockedExchangePointer(&Entry->ProcessId, GDI_GLOBAL_PROCESS);
+          (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, GDI_GLOBAL_PROCESS);
 
           hObj = (HGDIOBJ)((ULONG)(hObj) | GDI_HANDLE_STOCK_MASK);
           *phObj = hObj;
@@ -1246,7 +1266,7 @@
           /* WTF?! The object is already locked by a different thread!
              Release the lock, wait a bit and try again!
              FIXME - we should give up after some time unless we want to wait forever! */
-          (void)InterlockedExchangePointer(&Entry->ProcessId, PrevProcId);
+          (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, PrevProcId);
 
           DelayExecution();
           goto LockHandle;
@@ -1304,7 +1324,7 @@
 
 LockHandle:
     /* lock the object, we must not convert stock objects, so don't check!!! */
-    PrevProcId = InterlockedCompareExchangePointer(&Entry->ProcessId, ProcessId, LockedProcessId);
+    PrevProcId = _InterlockedCompareExchangePointer((PVOID*)&Entry->ProcessId, ProcessId, LockedProcessId);
     if(PrevProcId == ProcessId)
     {
       PETHREAD PrevThread;
@@ -1330,7 +1350,7 @@
               W32Process = (PW32PROCESS)OldProcess->Win32Process;
               if(W32Process != NULL)
               {
-                InterlockedDecrement(&W32Process->GDIObjects);
+                _InterlockedDecrement(&W32Process->GDIObjects);
               }
               ObDereferenceObject(OldProcess);
             }
@@ -1344,14 +1364,14 @@
             W32Process = (PW32PROCESS)NewOwner->Win32Process;
             if(W32Process != NULL)
             {
-              InterlockedIncrement(&W32Process->GDIObjects);
+              _InterlockedIncrement(&W32Process->GDIObjects);
             }
           }
           else
             ProcessId = 0;
 
           /* remove the process id lock and change it to the new process id */
-          (void)InterlockedExchangePointer(&Entry->ProcessId, ProcessId);
+          (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, ProcessId);
 
           /* we're done! */
           return;
@@ -1370,7 +1390,7 @@
              being deleted in the meantime (because we don't have aquired a reference
              at this point).
              FIXME - we should give up after some time unless we want to wait forever! */
-          (void)InterlockedExchangePointer(&Entry->ProcessId, PrevProcId);
+          (void)_InterlockedExchangePointer((PVOID*)&Entry->ProcessId, PrevProcId);
 
           DelayExecution();
           goto LockHandle;
@@ -1437,7 +1457,7 @@
 
 LockHandleFrom:
     /* lock the object, we must not convert stock objects, so don't check!!! */
-    FromPrevProcId = InterlockedCompareExchangePointer(&FromEntry->ProcessId, FromProcessId, FromLockedProcessId);
+    FromPrevProcId = _InterlockedCompareExchangePointer((PVOID*)&FromEntry->ProcessId, FromProcessId, FromLockedProcessId);
     if(FromPrevProcId == FromProcessId)
     {
       PETHREAD PrevThread;
@@ -1470,7 +1490,7 @@
             GDIOBJ_SetOwnership(HandleTable, CopyTo, NULL);
           }
 
-          (void)InterlockedExchangePointer(&FromEntry->ProcessId, FromPrevProcId);
+          (void)_InterlockedExchangePointer((PVOID*)&FromEntry->ProcessId, FromPrevProcId);
         }
         else
         {
@@ -1486,7 +1506,7 @@
              being deleted in the meantime (because we don't have aquired a reference
              at this point).
              FIXME - we should give up after some time unless we want to wait forever! */
-          (void)InterlockedExchangePointer(&FromEntry->ProcessId, FromPrevProcId);
+          (void)_InterlockedExchangePointer((PVOID*)&FromEntry->ProcessId, FromPrevProcId);
 
           DelayExecution();
           goto LockHandleFrom;




More information about the Ros-diffs mailing list