Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

Debugging .NET 2.0 Assembly from unmanaged Code in VS2010


:P
On this page:

I’ve run into a serious snag trying to debug a .NET 2.0 assembly that is called from unmanaged code in Visual Studio 2010. I maintain a host of components that using COM interop and custom .NET runtime hosting and ever since installing Visual Studio 2010 I’ve been utterly blocked by VS 2010’s inability to apparently debug .NET 2.0 assemblies when launching through unmanaged code.

Here’s what I’m actually doing (simplified scenario to demonstrate):

  • I have a .NET 2.0 assembly that is compiled for COM Interop
  • Compile project with .NET 2.0 target and register for COM Interop
  • Set a breakpoint in the .NET component in one of the class methods
  • Set debugging to point at unmanaged application (Visual FoxPro dev environment in this case)
  • Instantiate the .NET component via COM interop and call the method with a breakpoint

The result is that the COM call works fine but the debugger never triggers on the breakpoint.

If I now take that same assembly and target .NET 4.0 without any other changes everything works as expected – the breakpoint set in the assembly project triggers just fine. So it appears the debugging failure is specific to .NET 2.0 debugging  - it’s as if .NET is debugging the wrong runtime version and so failing to see the .NET 2.0 breakpoints.

The easy answer to this problem seems to be “Just switch to .NET 4.0” but unfortunately the application and the way the runtime is actually hosted has a few complications. Specifically the runtime hosting uses .NET 2.0 hosting and apparently the only reliable way to host the .NET 4.0 runtime is to use the new hosting APIs that are provided only with .NET 4.0 (which all by itself is lame, lame, lame as once again the promise of backwards compatibility is broken once again by .NET). So for the moment I need to continue using the .NET 2.0 hosting APIs due to the application requirements and runtime availability.

[updated 6/8/2010 with feedback from comments]

The Solution – provide a Runtime Hint

Thankfully David in the comments pointed at an MSDN forum post in the comments that addresses the problem. The issue is that the debugger needs to decide which version of the .NET runtime to use before the runtime is loaded. IOW, the debugger has no way to guess what version you are actually loading and so it loads the latest version.

The workaround to this problem is to temporarily provide a hint in the form of a .config file. In my test scenario I’m testing in the Visual FoxPro dev environment (vfp9.exe) and so I can create vfp9.exe.config in the install directory and specified the desired runtime load order (depending on availability on the machine):

<?xml version="1.0"?>
<configuration>
   <startup>
     <!--supportedRuntime version="v4.0.30319"/-->
     <supportedRuntime version="v2.0.50727"/>
     <supportedRuntime version="v1.1.4322"/>
     <supportedRuntime version="v1.0.3705"/>
   </startup>
</configuration>

 

To debug .NET 2.0 I have to explicitly set the  2.0 .NET runtime as highest version in the list. Originally I had added V4 to the list because I do actually want to allow V4 to be found and loaded by some of my applications. The debugger uses the config file as a hint to decide which runtime version to attach to when managed code fires up.

Note that on my machine having all those runtime versions in the config is not really necessary since I know the latest is there. But on deployed apps having a list of runtimes like above can be helpful in forcing the highest available version to load. Oddly it looks like some of the runtime hosting APIs like CorBindRuntimeEx() no longer respect these settings with .NET 4.0 when no explicit runtime version is specified and they fail to load the highest runtime version instead using 2.0. <shrug> There are new hosting APIs which kind of defeats the ability to specify version numbers since .NET 2.0 installs don’t have those new APIs.

The above config settings fixes my problem above nicely, although I’m pretty sure I will forget this in the future and hit this issue again - maybe this post will help me jog my memory or at least find it in a search. Love my blog as a crutch :-)


The Voices of Reason


 

Donnie Hale
June 07, 2010

# re: Debugging .NET 2.0 Assembly from unmanaged Code in VS2010?

Rick,

I definitely can't point you to a solution to your problem. However, there's a good article in the May 2010 MSDN Magazine on "Production Diagnostics" which, among other things covers debugging changes made in CLR 4. Some of the changes seem pretty dramatic. Perhaps there's something in that article which is helpful.

Donnie

Travis Illig
June 08, 2010

# re: Debugging .NET 2.0 Assembly from unmanaged Code in VS2010?

I've not run into this, but I have one of those feelings in the back of my mind that I thought I'd share... I'm wondering if this has anything to do with the side-by-side CLR hosting that .NET 4 introduces, where you can have .NET 4 and .NET 2 components running in the same process.

http://msdn.microsoft.com/en-us/library/ee518876.aspx

My hunch is that there's something weird going on where the unmanaged process is loading up one version of the CLR but the COM call is happening in a different version and, thus, VS isn't attaching to it.

Then again, I could be tooootally way off, but when I read "COM call from unmanaged code" I started thinking about all the problems I've had with classic ASP loading the wrong version of the CLR and failing to do COM calls to managed code. Felt like it could be a runtime thing.

Naveen
June 08, 2010

# re: Debugging .NET 2.0 Assembly from unmanaged Code in VS2010?

Can you attach your process to windbg and check which version of the framework is loaded? This could be your problem, especially with the Side-by-Side support from .NET 4.0

Or you can also start your unmanaged process within windbg and have a break-point on load of clr , command to do that is "sxe ld:clr" for .net 4.0 or "sxe ld:mscorjit" for .net 2.0. By this you can be certain which version of the framework is loaded. This would be a starting point to debug the issue.

Naveen

David Douglass
June 08, 2010

# re: Debugging .NET 2.0 Assembly from unmanaged Code in VS2010?


Rick Strahl
June 08, 2010

# re: Debugging .NET 2.0 Assembly from unmanaged Code in VS2010?

@David - Bingo! That's it. In fact, it looks like I jinxed myself with this as I explicitly added .NET 4.0 as the supported runtime FIRST in the config file. Removing the 4.0 reference let me debug properly. The explicit runtime version is required tho - with no hint the debugger still doesn't work either.

Rick Strahl
June 08, 2010

# re: Debugging .NET 2.0 Assembly from unmanaged Code in VS2010

@Naveen - thanks for the feedback. Good info. Actually I know what version of hte CLR loads as I have a method that returns runtime info. COM Interop and custom runtime loading is loading up the right version of the runtime. It's the debugger that's having issues and is the problem.

I do have some other odd version issues, but I'll post that in a separate post.

Rick Strahl
June 08, 2010

# re: Debugging .NET 2.0 Assembly from unmanaged Code in VS2010

I've updated the post here with the solution from from David's link to the MSDN forums. Thanks for the pointer David!

Shirin Patel
November 18, 2010

# re: Debugging .NET 2.0 Assembly from unmanaged Code in VS2010

I am having the same scenario but found another probelm while compiling application using VS.NET 2010 and targetting version 2.0.
I am unable to complie my code and getting mscorlib.dll issue. Below is the exact error :

The primary reference "Documentum.Interop.DFC, Version=5.3.0.620, Culture=neutral, PublicKeyToken=d8533ca61944ee9d" could not be resolved because it has an indirect dependency on the .NET Framework assembly "mscorlib, Version=5.3.0.620, Culture=neutral, PublicKeyToken=b77a5c561934e089" which has a higher version "5.3.0.620" than the version "2.0.0.0" in the current target framework. NET4MSCORLIB

Any Ideas......

Ulf
November 08, 2011

# re: Debugging .NET 2.0 Assembly from unmanaged Code in VS2010

In VS2010 it is also possible to debug the raw .NET framework source code. To debug errors in the framework, check out the following site for more information:
http://www.lazerwire.com/2011/11/vs2010-debug-net-assemblies.html

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024