title: app crashes when closing - using mixed mode DLL
body: <p>I'm getting an app crash when the program closes. Otherwise it runs fine.<br>
  Setup:<br>
  - Visual Studio 2012 (x64 Windows 7)<br>
  - mixed C++/CLI with native code DLL (native code is Boost Asio)<br>
  - CLR console application linked with the DLL  </p>
  
  <p>When I "debug" the crash the relevant message:</p>
  
  <blockquote>
    <p>Unhandled exception ... 0xC0020001: The string binding is invalid</p>
  </blockquote>
  
  <p>I found this MS blurb that describes the error: <a href="http://support.microsoft.com/kb/956195/en-us" rel="nofollow">crashes with 0xc0020001</a><br>
  To summarize it states this happens when managed code has been improperly mixed with unmanaged code.
  However I cannot determine where my code is mixed incorrectly.</p>
  
  <p>The file "UnmanagedBoostStuff.cpp" has its properties setting as
  <code>No Common Language RunTime Support</code>.</p>
  
  <p>And I read that when you include a header with native code to surround the include statement like:</p>
  
  <pre><code>// #pragma unmanaged
  // push managed state on to stack and set unmanaged state
  #pragma managed(push, off)
  #include "UnmanagedBoostStuff.h"
  // #pragma managed
  #pragma managed(pop)
  </code></pre>
  
  <p>DLL file 'MixedClrDLL.h'</p>
  
  <pre><code>// MixedClrDLL.h
  
  #pragma once
  
  /* 
   *
   * Add the following preprocessor definitions:
   *   BOOST_ALL_DYN_LINK
   *   _WIN32_WINNT=0x0501
   *
   * Turn off Precompiled Headers
   *
   * Make sure CLR is turned off for native code.
   */   
  
  // #pragma unmanaged
  // push managed state on to stack and set unmanaged state
  #pragma managed(push, off)
  #include "UnmanagedBoostStuff.h"
  // #pragma managed
  #pragma managed(pop)
  
  using namespace System;
  using namespace System::Runtime::InteropServices;
  
  namespace MixedClrDLL {
  
      public ref class SerialPort
      {
          BlockingReader *nativeClassPtr;
      public:
          SerialPort(System::String ^portName, int timeoutMillis);
  
          ~SerialPort() 
          { 
              if (m_isDisposed)
              {
                  return;
              }
              Diagnostics::Trace::WriteLine("destructor of SerialPort class");
              this-&gt;!SerialPort(); 
              m_isDisposed = true;
          }
  
          !SerialPort() 
          {
              Diagnostics::Trace::WriteLine("destruct-Finalizer of SerialPort class");
              delete nativeClassPtr;
              nativeClassPtr = nullptr;
          }
  
      private:
          bool m_isDisposed;
      };
  }
  </code></pre>
  
  <p>DLL file 'MixedClrDLL.cpp'</p>
  
  <pre><code>// This is the main DLL file.
  
  #include "stdafx.h"
  
  #include "MixedClrDLL.h"
  
  #include &lt;iostream&gt;
  
  using namespace MixedClrDLL;
  using namespace System;
  
  SerialPort::SerialPort(System::String ^portName, int timeoutMillis)
  {   
      // Marshal the managed string to unmanaged memory. 
      char* stringPointer = (char*) Marshal::StringToHGlobalAnsi(portName).ToPointer();
  
      try
      {   
          nativeClassPtr = new BlockingReader(stringPointer, timeoutMillis);
      }
  
      catch ( Runtime::InteropServices::SEHException^ ) 
      {
        std::cout&lt;&lt; "caught an SEH Exception in SerialPort constructor" &lt;&lt; std::endl;
        nativeClassPtr = nullptr;
        throw("Invalid com-port name");
      }
  
      Console::WriteLine("Execution continuing in SerialPort constructor: ");
  
      // Always free the unmanaged string.
      Marshal::FreeHGlobal(IntPtr(stringPointer));
  }
  </code></pre>
  
  <p>DLL file 'UnmanagedBoostStuff.h'</p>
  
  <pre><code>#pragma once
  
  #include &lt;boost/asio.hpp&gt;
  
  class BlockingReader
  {
  
  public: 
      BlockingReader(const char *name, size_t timeout);
      ~BlockingReader();
  
  private:    
      boost::asio::io_service io;
      boost::asio::serial_port port;
      size_t timeout; 
      boost::asio::deadline_timer timer;
      bool read_error;
  };
  </code></pre>
  
  <p>DLL file 'UnmanagedBoostStuff.cpp'</p>
  
  <pre><code>#include "stdafx.h"
  
  #include "UnmanagedBoostStuff.h"
  
  #include &lt;boost/bind.hpp&gt;
  #include &lt;iostream&gt;
  
  /*
   * Set "No Common Language RunTime Support" for the 
   * properties of this cpp file.
   *
   */
  BlockingReader::BlockingReader(const char *name, size_t timeout) :
      io(), port(io, name), timeout(timeout),
                                  timer(io),
                                  read_error(true)
  {
      std::cout&lt;&lt; "in Blocking Reader constructor: " &lt;&lt; name &lt;&lt; std::endl;
      port.set_option(boost::asio::serial_port_base::baud_rate(115200));
  }
  
  BlockingReader::~BlockingReader()
  {
      std::cout&lt;&lt; "in Blocking Reader DE-structor" &lt;&lt; std::endl;
      if (port.is_open())
      {
          std::cout&lt;&lt; " port is open - closing it" &lt;&lt; std::endl;
          port.close();
          //Sleep(100);
          if (port.is_open())
          {
              std::cout&lt;&lt; "Port is STILL open" &lt;&lt; std::endl;
          }
          else
          {
              std::cout&lt;&lt; "Port is now Closed" &lt;&lt; std::endl;
          }
      }
      else
      {
          std::cout&lt;&lt; "Port wasn't open open" &lt;&lt; std::endl;
      }
  }
  </code></pre>
  
  <p>And finally the CLR console app file 'ClrConsoleApp.cpp'</p>
  
  <pre><code>// ClrConsoleApp.cpp : main project file.
  
  #include "stdafx.h"
  #include &lt;iostream&gt;
  
  using namespace System;
  using namespace MixedClrDLL;
  
  void localTest();
  
  int main(array&lt;System::String ^&gt; ^args)
  {
      Console::WriteLine(L"Testing Mixed-Managed/Native");
      localTest();
  
      char ch;
      std::cout &lt;&lt; "enter a char to finish" &lt;&lt; std::endl;
      std::cin &gt;&gt; ch;
      std::cout &lt;&lt; "exiting" &lt;&lt; std::endl;
      return 0;
  }
  
  void localTest()
  {
      std::cout &lt;&lt; "in function" &lt;&lt; std::endl;
      SerialPort mixedClass("COM1", 500);
      std::cout &lt;&lt; "leaving function" &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>Thanks for your time.</p>
  
  <p>procdump output</p>
  
  <pre><code>&gt;procdump -g -ma -e -x C:\temp\StackOverflow\mixedTest\dumps C:\temp\StackOverflow\mixedTest\ClrConsoleApp\x64\Debug\ClrConsoleApp.exe
  
  ProcDump v7.1 - Writes process dump files
  Copyright (C) 2009-2014 Mark Russinovich
  Sysinternals - www.sysinternals.com
  With contributions from Andrew Richards
  
  Process:               ClrConsoleApp.exe (5428)
  CPU threshold:         n/a
  Performance counter:   n/a
  Commit threshold:      n/a
  Threshold seconds:     10
  Hung window check:     Disabled
  Log debug strings:     Disabled
  Exception monitor:     Unhandled
  Exception filter:      *
  Terminate monitor:     Disabled
  Cloning type:          Disabled
  Concurrent limit:      n/a
  Avoid outage:          n/a
  Number of dumps:       1
  Dump folder:           C:\temp\StackOverflow\mixedTest\dumps\
  Dump filename/mask:    PROCESSNAME_YYMMDD_HHMMSS
  
  
  Press Ctrl-C to end monitoring without terminating the process.
  
  [12:03:31] Exception: 04242420
  Testing Mixed-Managed/Native
  in function
  in Blocking Reader constructor: COM1
  Execution continuing in SerialPort constructor:
  leaving function
  in Blocking Reader DE-structor
   port is open - closing it
  Port is now Closed
  enter a char to finish
  s
  exiting
  [12:03:39] Exception: C0020001
  [12:03:39] Unhandled: C0020001
  [12:03:39] Dump 1 initiated: C:\temp\StackOverflow\mixedTest\dumps\ClrConsoleApp.exe_150227_120339.dmp
  [12:03:39] Dump 1 writing: Estimated dump file size is 93 MB.
  [12:03:40] Dump 1 complete: 93 MB written in 1.0 seconds
  [12:03:40] Dump count reached.
  </code></pre>
  
  <p>WinDbg analysis</p>
  
  <pre><code>Microsoft (R) Windows Debugger Version 6.3.9600.17298 AMD64
  Copyright (c) Microsoft Corporation. All rights reserved.
  
  Loading Dump File [C:\temp\StackOverflow\mixedTest\dumps\ClrConsoleApp.exe_150227_120339.dmp]
  User Mini Dump File with Full Memory: Only application data is available
  
  Comment: '
  *** procdump  -g -ma -e -x C:\temp\StackOverflow\mixedTest\dumps C:\temp\StackOverflow\mixedTest\ClrConsoleApp\x64\Debug\ClrConsoleApp.exe
  *** Unhandled exception: C0020001'
  
  ************* Symbol Path validation summary **************
  Response                         Time (ms)     Location
  Deferred                                       SRV*C:\temp\SymbolsCache*http://msdl.microsoft.com/download/symbols
  Symbol search path is: SRV*C:\temp\SymbolsCache*http://msdl.microsoft.com/download/symbols
  Executable search path is: 
  Windows 7 Version 7601 (Service Pack 1) MP (4 procs) Free x64
  Product: WinNt, suite: SingleUserTS
  Machine Name:
  Debug session time: Fri Feb 27 12:03:39.000 2015 (UTC - 5:00)
  System Uptime: 0 days 1:39:14.776
  Process Uptime: 0 days 0:00:08.000
  ....................................
  This dump file has an exception of interest stored in it.
  The stored exception information can be accessed via .ecxr.
  (1534.12fc): Unknown exception - code c0020001 (first/second chance not available)
  KERNELBASE!RaiseException+0x39:
  000007fe`fdd2940d 4881c4c8000000  add     rsp,0C8h
  0:000&gt; !analyze -v
  *******************************************************************************
  *                                                                             *
  *                        Exception Analysis                                   *
  *                                                                             *
  *******************************************************************************
  
  *** WARNING: Unable to verify checksum for MixedClrDLL.dll
  *** WARNING: Unable to verify checksum for mscorlib.ni.dll
  *** WARNING: Unable to verify checksum for ClrConsoleApp.exe
  
  FAULTING_IP: 
  KERNELBASE!RaiseException+39
  000007fe`fdd2940d 4881c4c8000000  add     rsp,0C8h
  
  EXCEPTION_RECORD:  ffffffffffffffff -- (.exr 0xffffffffffffffff)
  ExceptionAddress: 000007fefdd2940d (KERNELBASE!RaiseException+0x0000000000000039)
     ExceptionCode: c0020001
    ExceptionFlags: 00000001
  NumberParameters: 1
     Parameter[0]: ffffffff8007042b
  
  CONTEXT:  0000000000000000 -- (.cxr 0x0;r)
  rax=000000007799fe68 rbx=000007feec660000 rcx=000000000016ea20
  rdx=00000000000000c8 rsi=0000000000000000 rdi=000007fe957797f0
  rip=000007fefdd2940d rsp=000000000016f030 rbp=000000000016f350
   r8=0000000000000000  r9=0000000000000000 r10=000007fe957797f0
  r11=000000000016f070 r12=0000000000000001 r13=0000000000000001
  r14=000007feec660000 r15=0000000000000000
  iopl=0         nv up ei pl nz na pe nc
  cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000200
  KERNELBASE!RaiseException+0x39:
  000007fe`fdd2940d 4881c4c8000000  add     rsp,0C8h
  
  DEFAULT_BUCKET_ID:  WRONG_SYMBOLS
  
  PROCESS_NAME:  ClrConsoleApp.exe
  
  ERROR_CODE: (NTSTATUS) 0xc0020001 - The string binding is invalid.
  
  EXCEPTION_CODE: (NTSTATUS) 0xc0020001 - The string binding is invalid.
  
  EXCEPTION_PARAMETER1:  ffffffff8007042b
  
  NTGLOBALFLAG:  70
  
  APPLICATION_VERIFIER_FLAGS:  0
  
  APP:  clrconsoleapp.exe
  
  ANALYSIS_VERSION: 6.3.9600.17298 (debuggers(dbg).141024-1500) amd64fre
  
  MANAGED_STACK: !dumpstack -EE
  OS Thread Id: 0x12fc (0)
  Current frame: 
  Child-SP         RetAddr          Caller, Callee
  
  PRIMARY_PROBLEM_CLASS:  WRONG_SYMBOLS
  
  BUGCHECK_STR:  APPLICATION_FAULT_WRONG_SYMBOLS
  
  LAST_CONTROL_TRANSFER:  from 000007fef51e8194 to 000007fefdd2940d
  
  STACK_TEXT:  
  : KERNELBASE!RaiseException+0x39
  : clr!COMPlusThrowBoot+0x24
  : clr!TheUMEntryPrestubWorker+0x2e
  : clr!TheUMEntryPrestub+0x3e
  : MixedClrDLL!_CRT_INIT+0x2df
  : MixedClrDLL!__DllMainCRTStartup+0x11f
  : MixedClrDLL!_DllMainCRTStartup+0x31
  : mscoreei!CorDllMain+0x1e5
  : mscoree!ShellShim__CorDllMain+0xe1
  : mscoree!CorDllMain_Exported+0x37
  : ntdll!LdrShutdownProcess+0x1db
  : ntdll!RtlExitUserProcess+0x90
  : mscoreei!RuntimeDesc::ShutdownAllActiveRuntimes+0x27b
  : mscoreei!CLRRuntimeHostInternalImpl::ShutdownAllRuntimesThenExit+0x14
  : clr!EEPolicy::ExitProcessViaShim+0x6d
  : clr!SafeExitProcess+0x9d
  : clr!HandleExitProcessHelper+0x3e
  : clr!_CorExeMainInternal+0xf9
  : clr!CorExeMain+0x14
  : mscoreei!CorExeMain+0xe0
  : mscoree!CorExeMain_Exported+0x57
  : kernel32!BaseThreadInitThunk+0xd
  : ntdll!RtlUserThreadStart+0x1d
  
  STACK_COMMAND:  ~0s; .ecxr ; kb
  
  FOLLOWUP_IP: 
  clr!TheUMEntryPrestubWorker+2e
  000007fe`f529ff3d e8de13acff      call    clr!GetThread (000007fe`f4d61320)
  
  SYMBOL_STACK_INDEX:  2
  
  SYMBOL_NAME:  clr!TheUMEntryPrestubWorker+2e
  
  FOLLOWUP_NAME:  MachineOwner
  
  MODULE_NAME: clr
  
  IMAGE_NAME:  clr.dll
  
  DEBUG_FLR_IMAGE_TIMESTAMP:  5348a1ef
  
  FAILURE_BUCKET_ID:  WRONG_SYMBOLS_c0020001_clr.dll!TheUMEntryPrestubWorker
  
  BUCKET_ID:  X64_APPLICATION_FAULT_WRONG_SYMBOLS_clr!TheUMEntryPrestubWorker+2e
  
  ANALYSIS_SOURCE:  UM
  
  FAILURE_ID_HASH_STRING:  um:wrong_symbols_c0020001_clr.dll!theumentryprestubworker
  
  FAILURE_ID_HASH:  {44cb5842-609a-8fdb-42fb-cf958ade10f6}
  
  Followup: MachineOwner
  ---------
  </code></pre>