Hi, In Redland# we use the pattern described by Microsoft for using IDisposable to wrap unmanaged resources, described here: http://makeashorterlink.com/?Y3861282A
I have a private member of type IntPtr set to the unmanaged resource, and a P/Invoke to a cleanup C function is made in the Dispose call, and then the member set to IntPtr.Zero, as described under "Implementing a Dispose method". The problem is that -- when Dispose is run from the Finalizer (that is, Dispose wasn't called before the object was GC'd) -- it seems the IntPtr member has already been finalized, and there's a NullReferenceException generated. Under Mono 1.0.4 this prints out: Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object And then the runtime hangs. This happens only occasionally, and less frequently if I'm generating trace output. Many of the traced sessions look a bit like this: ENTER: (wrapper runtime-invoke) System.Object:runtime_invoke_void (object,intptr,intptr,intptr)([Redland.Serializer:0x8096a90], (nil), 0xb6a659c8, 0xb619e2a0, ). ENTER: Redland.Serializer:Finalize ()(this:0x8096a90[Redland.Serializer test.exe], ) . . ENTER: Redland.Serializer:Dispose (bool)(this:0x8096a90[Redland.Serializer test.exe], 0, ) . . . ENTER: (wrapper managed-to-native) Redland.Serializer:librdf_free_serializer (intptr)(0x8172ba8, ) . . . . ENTER: (wrapper runtime-invoke) System.Object:runtime_invoke_void (object,intptr,intptr,intptr)([System.NullReferenceException:0x8098c90], (nil), (nil), 0xb619e3b0, ) . . . . . ENTER: System.NullReferenceException:.ctor ()(this:0x8098c90[System.NullReferenceException test.exe], ) . . . . . . ENTER: Locale:GetText (string)([STRING:0x8111c78:A null value was found where an object instance was required.], ) . . . . . . LEAVE: Locale:GetText (string)[STRING:0x8111c78:A null value was found where an object instance was required.] . . . . . LEAVE: System.NullReferenceException:.ctor () . . . . LEAVE: (wrapper runtime-invoke) System.Object:runtime_invoke_void (object,intptr,intptr,intptr)[OBJECT:(nil)] EXCEPTION handling: NullReferenceException EXCEPTION: finally clause 0 of Redland.Serializer:Finalize () . . . . ENTER: System.Object:Finalize ()(this:0x8096a90[Redland.Serializer test.exe], ) . . . . LEAVE: System.Object:Finalize () EXCEPTION: catch found at clause 0 of (wrapper runtime-invoke) System.Object:runtime_invoke_void (object,intptr,intptr,intptr) What I see happening above is the NullReferenceException being thrown when it attempts to pass the value of the private IntPtr to the C cleanup function, librdf_free_serializer(). I pulled Mono SVN HEAD to see if things worked any different there. The good news is that we no longer seem to get the random hangs that 1.0.4 generates, but the trace shows that the NullReferenceException thing is still happening. At the best, this means memory leaks are going to happen. Have I got something wrong here, or is there a bug with finalizing classes? The code is structured just the way the MSDN example suggests. -- Edd _______________________________________________ Mono-list maillist - [email protected] http://lists.ximian.com/mailman/listinfo/mono-list
