Click here to Skip to main content
15,847,427 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have a mixed mode dll (C++/Cli) that is referenced in a C# application. It crashes with the error: name_here.dll has caused an access violation exception(0xC0000005) when trying to read from memory location 0x00000000 on thread 243.

What I have tried:

I ran DebugDiag on a crashdump and it shows that error together with the following information: GC is running in this process. The thread that triggered the GC is 274.

Then DebugDiag report shows this warning: The following threads are waiting for .net garbage collection to finish. Thread 274 triggered the garbage collection.The garbage collector thread wont start doing its work till the time the threads which have pre-emptive GC disabled have finished executing. The following threads have pre-emptive GC disabled 274.

Then there's another warning regarding the initial thread that throws the access violation, thread 243: Detected possible blocking or leaked critical section at <address_here> owned by thread 243.

Not exactly sure how to approach this or what I could be doing wrong. Anyone has had this issue. Is thread 274 causing a deadlock on itself? Any idea would be very much appreciated.

This is the stack trace for the thread that’s triggering GC:
clr!StackFrameIterator::NextRaw+4
clr!GCToEEInterface::GcScanRoots+4e3
clr!WKS::gc_heap::mark_phase+197
clr!gc_heap::gc1+a3
clr!WKS::gc_heap::garbage_collect+54c
clr!WKS::GCHeap::GarbageCollectGeneration+10d
clr!WKS::gc_heap::trigger_gc_for_alloc+2d
clr!JIT_New+4d6
[my user code here]
This is the thread that’s causing the Access Violation error:
ntdll!NtWaitForMultipleObjects+14
KERNELBASE!WaitForMultipleObjectsEx+ef
KERNELNASE!WaitForMultipleObjects+e
kernel32!WerpReportFaultInternal+4b0
kernel32!WerpReportFault+73
KERNELBASE!UnhandledExceptionFilter+23b
ntdll!RtlUserThreadStart$filt$0+38
ntdll!_C_specific_handler+96
ntdll!RtlpExecuteHandlerForException+d
ntdll!RtlDispatchException+373
ntdll!KiUserExceptionDispatch+3a
This is the stack trace for the GC thread according to DebugDiag:
ntdll!NtWaitForSingleObject+14
KERNELBASE!WaitForSingleObjectEx+8f
clr!CLREventWaitHelper2+3c
clr!CLREventWaitHelper+1f
clr!CLREventBase::WaitEx+7c
clr!WKS::gc_heap::bgc_thread_function+9f
clr!Thread::intermediateThreadProc+86
kernel32!BaseThreadInitThunk+14
ntdll!RtlUserThreadStart+21
And this is the finalizer thread:
ntdll!NtWaitForSingleObject+14
KERNELBASE!WaitForSingleObjectEx+8f
clr!CLREventWaitHelper2+3c
clr!CLREventWaitHelper+1f
clr!CLREventBase::WaitEx+7c
clr!FinalizerThread::WaitForFinalizerEvent+44
clr!FinalizerThread::FinalizerThreadWorker+54
clr!ManagedThreadBase_DispatchInner+39
clr!ManagedThreadBase_DispatchMiddle+6c
clr!ManagedThreadBaseDispatchOuter+75
clr!FinalizerThread::FinalizerThreadStart+10a
clr!Thread::intermediateThreadProc+86
kernel32!BaseThreadInitThunk+14
ntdll!RtlUserThreadStart+21
Also a lot of threads are waiting for GC to finish and they have this in their call stack:
ntdll!NtWaitForSingleObject+14
KERNELBASE!WaitForSingleObjectEx+8f
clr!CLREventWaitHelper2+3c
clr!CLREventWaitHelper+1f
clr!CLREventBase::WaitEx+7c
clr!WKS::GCHeap::WaitUntilGCComplete+2b
clr!Thread::RareDisablePreemptiveGC+180
Posted
Updated 9-Dec-21 19:27pm
v3
Comments
Shao Voon Wong 10-Dec-21 2:40am    
If you run your application under the VS debugger, it can show you the call stack whenever the exception happens. Your code is accessing a NULL pointer which causes the access violation.
codefast1993 10-Dec-21 19:34pm    
Hi Shao, thank you for answering. The difficult part is that this happens only in release mode in production, meaning the code is optimized. When I took a look at the stack at the variables that were not optimized away I could not find anything suspicious.
Shao Voon Wong 11-Dec-21 0:19am    
Not possible for anyone to find the error without access to the source code. I suggest you search in your codebase for all the "null", "NULL" and "nullptr" assignments and check if the null pointer is used without first initializing with a valid object/array.
Shao Voon Wong 11-Dec-21 21:21pm    
In .NET, the finalizer can be called twice. Once you have run the finalizer, remember to call GC.SuppressFinalize(this); to prevent the 2nd run else you get an exception because the object has already been cleaned up. Below is the link on how to implement IDisposable pattern.

https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose
Shao Voon Wong 12-Dec-21 0:35am    
If the finalizer throwing exception in GC is indeed the problem, I propose 4 solutions. Solution A: Call GC.SuppressFinalize(this); at the end of all your C# finalizers. Solution B: In your C# finalizers and C++/CLI destructors, check a reference or pointer is not null before using it and set it to null after freeing/cleaning up. Solution C: Put the try-catch block in all your C# finalizers and C++/CLI destructors to catch the Access Violation exception. Solution D: Best if implementing all three A, B and C solutions but note A, B and C alone is sufficient to fix the problem on their own.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900