[ros-dev] Re: [ros-svn] [ion] 13832: - FreeLdr Part II (ntoskrnl is now relocated, removes 3GB compiler flag). Note that there is a bug in LD which Filip and I are examining, so do not try this yet.

Hartmut Birr hartmut.birr at gmx.de
Mon Mar 7 22:10:39 CET 2005


Hi,

I can fix my problem by protecting the access to some entries of the
object header with a global spinnlock, but I doesn't like this. Has
anyone a better idea?

- Hartmut



Hartmut Birr schrieb:

>Alex Ionescu schrieb:
>
>  
>
>>James Tabor wrote:
>>
>>    
>>
>>>BugCheck Alert!
>>>
>>>
>>>      
>>>
>>Hmm...looks like after reverting Thomas's patch and using Hartmut's,
>>the problems are happening again.
>>So, it would seem that Thomas' patch is more correct? Or perhaps both
>>should be used?
>>T/H: Let me know!
>>
>>    
>>
>Hi,  
>
>I've written a little test program which does always crash ros with my
>patch on the smp machine (up not tested). The program does create 10
>threads which try to open a non existing registry key in an endless
>loop. It does not crash with Thomas' patch. His patch adds one reference
>to much to the first parsed/opened key. This makes it impossible to
>delete a key and to unload the registry at shut down. I think we have a
>problem outside from the registry. It seems there is a gap between the
>deleting of an object after the last dereference operation and the next
>create operation for a new object with the same name. One thread has
>reopend the object and use it and the other delete the same object. I
>see very often values of 0xcccccxxx on bug checks and the wrong
>reference value -858993460 is also 0xcccccccc.   
>
>- Hartmut
>
>  
>
>------------------------------------------------------------------------
>
>_______________________________________________
>Ros-dev mailing list
>Ros-dev at reactos.com
>http://reactos.com:8080/mailman/listinfo/ros-dev
>

-------------- next part --------------

M:\Sandbox\ros_work\reactos>set SVN_EDITOR=notepad 

M:\Sandbox\ros_work\reactos>d:\programme\subversion\bin\svn.exe diff ntoskrnl\ob\object.c        
Index: ntoskrnl/ob/object.c
===================================================================
--- ntoskrnl/ob/object.c	(revision 13857)
+++ ntoskrnl/ob/object.c	(working copy)
@@ -22,6 +22,7 @@
   POBJECT_HEADER ObjectHeader;
 } RETENTION_CHECK_PARAMS, *PRETENTION_CHECK_PARAMS;
 
+KSPIN_LOCK ObpLock = 0;
 
 /* FUNCTIONS ************************************************************/
 
@@ -818,6 +819,8 @@
 			   IN KPROCESSOR_MODE AccessMode)
 {
    POBJECT_HEADER Header;
+   KIRQL oldIrql;
+   NTSTATUS Status;
    
    /* NOTE: should be possible to reference an object above APC_LEVEL! */
 
@@ -849,22 +852,32 @@
 	DPRINT("eip %x\n", ((PULONG)&Object)[-1]);
      }
  
-   if (Header->CloseInProcess)
-   {
-      if (Header->ObjectType == PsProcessType)
-        {
-	  return STATUS_PROCESS_IS_TERMINATING;
-	}
-      if (Header->ObjectType == PsThreadType)
-        {
-	  return STATUS_THREAD_IS_TERMINATING;
-	}
-      return(STATUS_UNSUCCESSFUL);
-   }
+   KeAcquireSpinLock(&ObpLock, &oldIrql);
 
-   InterlockedIncrement(&Header->RefCount);
+   if (Header->CloseInProcess ||
+       (0 == Header->RefCount && 0 == Header->HandleCount && !Header->Permanent))
+     {
+       if (Header->ObjectType == PsProcessType)
+         {
+	   Status = STATUS_PROCESS_IS_TERMINATING;
+	 }
+       else if (Header->ObjectType == PsThreadType)
+         {
+	   Status = STATUS_THREAD_IS_TERMINATING;
+	 }
+       else
+         {
+           Status = STATUS_UNSUCCESSFUL;
+         }
+     }
+   else
+     {
+       InterlockedIncrement(&Header->RefCount);
+       Status = STATUS_SUCCESS;
+     } 
+   KeReleaseSpinLock(&ObpLock, oldIrql);
    
-   return(STATUS_SUCCESS);
+   return Status;
 }
 
 
@@ -960,7 +973,7 @@
 
 STATIC NTSTATUS
 ObpDeleteObjectDpcLevel(IN POBJECT_HEADER ObjectHeader,
-			IN LONG OldRefCount)
+			IN KIRQL oldIrql)
 {
   if (ObjectHeader->RefCount < 0)
     {
@@ -981,11 +994,14 @@
   if (ObjectHeader->CloseInProcess)
     {
       KEBUGCHECK(0);
+      KeReleaseSpinLock(&ObpLock, oldIrql);
       return STATUS_UNSUCCESSFUL;
     }
   ObjectHeader->CloseInProcess = TRUE;
   
-  switch (KeGetCurrentIrql ())
+  KeReleaseSpinLock(&ObpLock, oldIrql);
+  
+  switch (oldIrql)
     {
     case PASSIVE_LEVEL:
       return ObpDeleteObject (ObjectHeader);
@@ -1043,18 +1059,23 @@
 ObfReferenceObject(IN PVOID Object)
 {
   POBJECT_HEADER Header;
+  KIRQL oldIrql;
 
   ASSERT(Object);
 
   Header = BODY_TO_HEADER(Object);
 
+  KeAcquireSpinLock(&ObpLock, &oldIrql);
+
   /* No one should be referencing an object once we are deleting it. */
-  if (Header->CloseInProcess)
+  if (Header->CloseInProcess || 
+      (0 == Header->RefCount && 0 == Header->HandleCount && !Header->Permanent))
     {
       KEBUGCHECK(0);
     }
 
   (VOID)InterlockedIncrement(&Header->RefCount);
+  KeReleaseSpinLock(&ObpLock, oldIrql);
 }
 
 
@@ -1081,9 +1102,12 @@
   LONG NewRefCount;
   BOOL Permanent;
   ULONG HandleCount;
+  KIRQL oldIrql;
 
   ASSERT(Object);
 
+  KeAcquireSpinLock(&ObpLock, &oldIrql);
+
   /* Extract the object header. */
   Header = BODY_TO_HEADER(Object);
   Permanent = Header->Permanent;
@@ -1101,8 +1125,12 @@
       HandleCount == 0 &&
       !Permanent)
     {
-      ObpDeleteObjectDpcLevel(Header, NewRefCount);
+      ObpDeleteObjectDpcLevel(Header, oldIrql);
     }
+  else
+    {
+      KeReleaseSpinLock(&ObpLock, oldIrql);
+    }
 }
 
 


More information about the Ros-dev mailing list