I have a program that is a C# wrapper for a program originally written in C/C++. The code goes through a SWIG process make the dlls accessible. Recently this code has started to crash intermittently with an access violation, but only when run in parallel with other similar code, suggesting a shared resource. However, there is no clear shared resource.
Also, the program always seems to complete (with proper output) and the access violation occurs on exit (when stepping through the code with VS19 the intermittent access violation occurs after the final return statement). I have tried putting handlers for AppDomain.ProcessExit and for UnhandledException, but it never hits that code. Even when VS19 reports an access violation in the output window, it always reports that the code has exited with 0, so I can't even be sure if this is the access violation being reported to the OS.
So...running from the command line I was able to get it to crash intermittently with rc -1073741819 (0xc0000005).
Running procdump.exe I was able to get a dump of the crash, with this error: Unhandled exception at 0x00007FFB0FDDFCA0 (iertutil.dll) in XXXXXXXXXXXXXXX.exe_220719_142518.dmp: 0xC0000005: Access violation reading location 0x0000000000000000.
The call stacks are not very revealing. While analyzing the dump in Visual Studio it says that symbols are loaded for all of my dlls, but when I look at the call stack of the access violation, it only shows me a very limited stack of the windows calls (see link).
call stacks from the dump after the access violation
The actual access violation is in _purecall, but again this crash is occurring after the return statement in my C# main. I cannot even figure out why wininet.dll!InternetGetConnectedState() would be called at that point in the code.
I suspect that there is something in one of the C or C++ libraries that is putting in an atexit call for something that the C# has already cleared. I have tried forcing garbage collection to occur earlier in the C# code, but this does not cause an access violation.
So the questions are
- What could be causing this access violation on program exit, and how can I debug it?
- Why are only the windows calls seen in the call stack from procdump when all of my symbols are reported to be loaded?
I was experiencing exactly the same issue, and for a use case similar to the one mentioned in the original question.
Before providing a tentative answer and solution to the problem, allow me to provide more insights into the problem:
The common patterns between my use case and the originally posted one are:
Interestingly enough, in my case, the crash was manifesting always in .NET Framework (versions 3.5 up to 4.8), and NOT manifesting in .NET Core and .NET 5 and newer.
My crash stack trace looked exactly like the one referenced in the original question:
The other interesting thing is that the 100% identical C++ code (implemented in a DLL, and which the .NET app is calling into, via SWIG and P/Invoke) executed via a C++ .exe app, did not show any crash.
So, this was happening only with C# app builds targeting .NET Framework versions up to 4.8.
The following C# code has completely fixed my problem:
While I cannot provide a completely rational technical explanation as to why the 1-liner call to
InternetConnectedState()(via P/Invoke) works, I can only speculate the following:So, the proposed fix is to make at least one call to
InternetGetConnectedState()from within the C# Main() (through P/Invoke), as early as possible, which probably makes the WinINet API initializing its internal global state much earlier, from within C# / .NET managed layer, AND therefore maintaining a longer lifetime / scope of such global state.It may be worth taking my solution for a spin, to see if it fixes your problem.