RedGate ANTS Performance Profiler Crashes The Target Process

Print

For about a week I've been banging my head against the wall trying to figure out the reason why attempting to profile one of my applications caused the target process to crash immediately after loading. The crash was an nasty access violation (error code: 0xc0000005), of the variety you'd experience if your process was touching memory it shouldn't be touching, or doing something funky at a very low level..

Spoiler alert: It has to do with having ngen'd assemblies installed on the system!

If you'd like to stick around for the full story, here's some background information. I was using the RedGate ANTS Performance Profiler Professional version 8.5 and this particular instance was the first time I had problems with it.

After a little troubleshooting I was able to find out the following

  • attaching to the process after it was separately started worked correctly - no crashing
  • starting a profiling session with the lowest level (Sample Methdod-Level Timing) also worked correctly
  • profiling on any level other than the lowest would cause the application to crash
  • profiling other applications seemed to work correctly, regardless of the profiling level (* more on this later)

After all this I was at a loss. I thought for sure the problem was in the initialization code of my application so I started removing code, introducing delays and tracing, all in an attempt to isolate the problem area.

I also tried profiling the application while running under the RedFlag Debugger. This provided some valuable insight. As it turns out, the crash seemed to be occurring when a call was made to activate a window. But it seemed to be coming from within the .NET framework.

I kept removing code, focusing on any code that may have anything, even remotely, to do with making a window active. The application I was profiling was a Windows Forms application so there were a few forms being displayed in the beginning. In the end I reduced the application to a generic Windows Forms program that only displayed a plain vanilla form

using System;
using System.Windows.Forms;

namespace Test
{
   static class Program
   {
      [STAThread]
      static void Main()
      {
         Form frm = new From();
         Application.Run(frm);
      }
   }
}

And this was the final clue that something was fundamentally wrong with my environment. When I reduced my application to this and tried profiling it, it still crashed. The exact same way.

That's when I realized that none of the other applications that I had used the profiler on, and which were working correctly (** as mentioned above), were Windows Forms applications. So it seemed the problem was limited to profiling Windows Forms application on my computer.

Subsequently I tried profiling the original application on a different computer and it worked correctly, regardless of the profiling level selected. This proved beyond a doubt that there was something else on my development machine that would interact with the profiler causing the target process to crash.

After more research and help from RedGate's customer support I tracked down the problem to having certain assemblies with native images generated with the /profile option installed on my system. In particular the culprits were:

  • System.Windows.Forms
  • System
  • mscorlib

The fix was to uninstall all the ngen'd assemblies from the system, both from the 64-bit environment as well as the 32-bit. To do so I had to run the following command from an elevate Visual Studio command prompt (once for the 32-bit and once for 64-bit)

ngen.exe uninstall * /profile

Once I got to this point, a quick search on the internet highlighted the problem as being a known incompatibility between profilers and ngen'd assemblies, when the /profile option is used.

When an IL instrumenting profiler detects that an NGEN /Profile assembly exists, this assembly is immediately loaded, even though in fact it cannot be instrumented. According to Microsoft, this issue will be fixed in their next release: there will be a flag in the Profiling API that the instrumenting profiler can turn on, which will cause it to ignore the existance of NGEN /Profile assemblies and go back to JITing.

The reason I had these native images installed on my development machine is because I had previously installed the SlimDX development kit. Apparently, the installer for SlimDX installs native images of .NET assemblies to speed up applications developed with SlimDX.

It is worth noting that removing the ngen'd assemblies that were generated with the profile option will not cause any harm.

is the founder of Donaq, a software development consulting company with a focus on mobility. You can find Mike on Google+ and on LinkedIn.
Design copyright (c) Miky Dinescu