Static variable in native method causes exception c0020001 during process exit - by Bradley Grainger

Status : 

  Won't Fix<br /><br />
		Due to several factors the product team decided to focus its efforts on other items.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.

Sign in
to vote
ID 336844 Comments
Status Closed Workarounds
Type Bug Repros 7
Opened 4/3/2008 5:37:49 PM
Access Restriction Public


1) a mixed managed/native C++ assembly is loaded by a .NET application, and
2) that assembly contains a managed C++ method that (during regular program execution) calls a native C++ method, and
3) that native C++ method contains a static variable, and
4) that static variable is of a native type with a destructor,
then the following exception occurs during process exit:

Unhandled exception at 0x75df42eb (kernel32.dll) in App.exe: 0xC0020001: The string binding is invalid.

This occurs because a managed destructor for the static variable has been registered with the atexit function. This registered function is called when DllMain is called with DLL_PROCESS_DETACH, which happens when the C++ assembly is unloaded at exit. However, the CLR has already been shut down, so the attempt to transition back to managed code fails, and exception 0xc0020001 is thrown. The compiler should register a native destructor with atexit, not a managed destructor.
Sign in to post a comment.
Posted by SergeLalonde1 on 2/4/2014 at 7:34 AM
I've also run into this bug in VS2010.
The workaround provided probably works, but involves a lot of rewriting of code in a large application, which is simply not practical especially when the bug is found late in the development cycle just before releasing!
It's also difficult to find where this might occur in a large application since the crash at shutdown will only happen if the local static object was constructed (since the destructor is registered with atexit only if it's been constructed).
So this is a bug that can be lurking anywhere in the code that a customer can encounter at any time, but that our regression tests won't find. Then, try to get the user to explain step-by-step what he did. Might as well ask for the moon.
I hope that this is fixed in VS2012 or VS2013, otherwise, why offer compiler features like C++/CLI that are broken?
Posted by WernerK on 2/9/2011 at 5:20 AM
I had the same problem after removing the source for ManagedWrapper minitialize/mterminate which I had added according to years ago with VS 2003 because of linker errors.
I had removed this old source because of Build output messages
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\_vcclrit.h(33): warning CRT1001: _vcclrit.h is deprecated
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\_vcclrit.h(124): warning C4996: '__lock_handle': These manual initialisation functions (plus link /noentry) are no longer appropriate for managed code DLLs. Instead, use a normal DLL entrypoint. See online help for more information.
1>         C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\_vcclrit.h(93): Siehe Deklaration von '__lock_handle'
Without ManagedWrapper I get errors when the app starts and ends; when I include/activate ManagedWrapper again then the problems disappear.
Maybe usage of ManagedWrapper as described in (and adapted from old Managed Extensions (/clr:OldSyntax) to new /clr mode) is another useful workaround for this problem.
Posted by David Furtney on 8/11/2008 at 12:53 PM
We ran into this as well. The only difference is that NativeMethod with the static variable was compiled as managed. I don't think there is any doubt this is a compiler bug. We worked around the issue by moving the static variable to file scope.
Posted by Microsoft on 4/21/2008 at 2:56 PM
The Visual C++ team has triaged the issue you reported with the following message:

The suggested way to work-around this is to use to compilation units, and not rely on #pragma unmanaged/managed (which is pretty fragile).

Here's a workaround:

int NativeMethod(int i);

public ref class Managed
        int CallNative(int n)
                return NativeMethod(n);

class Native
        Native() { }
        ~Native() { }

int NativeMethod(int i)
        static Native n;
        return i * 2;

cl /MDd /Zi /clr /c t.cpp
cl /EHa /MDd /Zi /c n.cpp
link /dll t.obj n.obj /debug

For further information, you may want to consult one of these resources:
1. Visual C++ triage guidelines:
2. MSDN forums:

Thank you for taking time to send us feedback,
The Visual C++ Team
Posted by Microsoft on 4/4/2008 at 3:03 AM
Thanks for your feedback. We are escalating this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.

Thank you,
Visual Studio Product Team