Wednesday, April 18, 2007

NCover Problems / Fixes - Part 1

From time to time I try to chip in with support on the NCover forums, not only with NCoverExplorer issues but NCover as well since they are so dependent. There are a bunch of issues which come up repeatedly, particularly for people new to using NCover.

In a perfect world (future release?) NCover itself could offer some more helpful error messages, but where is the fun in that? For now at least it is more a case of deciphering the clues from the console output and coverage.log files.

Hopefully this series of posts may help a few people and reduce the times I end up repeating myself on the forums, so win-win if it works for you. My examples will use NCover 1.5.7. You should also take a look at the NCover FAQ which is included in your installation. I've got a copy here too if that helps...


Profiled process terminated. Profiler connection not established.

Easily the most common problem people stumble on. As shown below your application starts (in this case unit tests), but after a delay of 60 seconds or so you get this message.

>E:\apps\NCover\ncover.console.exe E:\apps\nunit\nunit-console.exe MyTests.dll
NCover.Console v1.5.7 - Code Coverage Analysis for .NET - http://ncover.org
Copyright (c) 2004-2006 Peter Waldschmidt

Command: E:\apps\nunit\nunit-console.exe
Command Args: "MyTests.dll"
Working Directory:
Assemblies:
Coverage Xml: Coverage.Xml
Coverage Log: Coverage.Log

Waiting for profiled application to connect...
NUnit version 2.2.8

Copyright (C) 2002-2003 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole.
Copyright (C) 2000-2003 Philip Craig.
All Rights Reserved.

OS Version: Microsoft Windows NT 5.1.2600 Service Pack 2 .NET Version: 2.0.50727.42
.
Tests run: 1, Failures: 0, Not run: 0, Time: 0.016 seconds

Connected
Profiled process terminated. Profiler connection not established.


Most likely this is due to one of two reasons I know of:

(1) You are profiling a windows service or IIS - this feature has been reported as currently broken.

(2) You are profiling an executable - but Coverlib.dll was not COM registered

Unfortunately the windows service/IIS testing fell down the cracks for 1.5.7 for those of you trying to use this feature. You can monitor some of the threads on it here and here. Personally for my applications I remove the need to profile services at all. By making the windows service a super lightweight wrapper and moving all the implementation out into classes that are more easily tested there is no need to unit test what remains.

I appreciate however there are scenarios for people where they do want coverage of services for integration testing etc - all I can say for now is that Peter is on the case. Let's now focus on the more common scenario for people trying to profile executables and offer some background info.

NCover Basics

So what's that registration bit about then - surely NCover is a .NET application? Sure, some of it is - but the really clever bit of NCover is the C++ implementation of ICorProfiler in Coverlib.dll, which is a callback class for use with the .NET Profiler API. The requirements of the API are that the callback class has to be COM registered and it cannot be written in managed code. By using some environment variables set within NCover before launching your process, the .NET profiler is able to be "switched on" to make the API callbacks while your process is running.

This is the heart of NCover - it monitors the loading of AppDomains and modules, intercepts the JIT execution of methods and injects it's own instructions to monitor the execution counts. This data is then pumped back to the "managed code" part of NCover, which munges the data together to produce the coverage.xml output you know and love for NCoverExplorer to manipulate.

So the "profiler connection not established" message indicates that there was some sort of problem with communication between NCover and the .NET profiler. As illustrated with the windows service problem above this message doesn't always mean that it was caused by a registry problem, but many times it is and it's worth double-checking first.

NCover Installation / XCopy Deployment

If you installed NCover using the MSI installer, then it will have automatically COM registered CoverLib.dll for you in "C:\Program Files\NCover\". If however, you are like many people intending to run NCover using an xcopy style deployment mechanism as with other tools such as NUnit, then you must remember about this requirement.

So let's say you do want to relocate NCover to a tools subfolder in a source controlled directory - what's the idiot-proof way to do it?

Firstly, make sure you copy all the NCover files from the installation folder above. Make sure you don't skip the Microsoft.VC80.CRT.manifest, MSVCP80.dll or MSVCR80.dll files. If you do skip them, then an attempt to register Coverlib.dll will fail on machines without these .dlls already in a path somewhere. You may find it works on your development machine with VS.Net installed, but then fails on your build server.

Secondly, make sure you run the NCover uninstall which will clean up the registry as well as the installed files. So now your machine should be back in "pristine" condition.

Options For Registering NCover

So having identified that when running NCover.Console.exe you need to ensure that Coverlib.dll is registered - what are your options?

1. If you stuck with the default NCover installation, have no need for locating it elsewhere and need only one version of NCover for all your applications. Congratulations - you shouldnt have seen the problem above! If you did, you should manually re-register it using regsvr32 or try running the installer again.

2. The NAnt/MSBuild tasks I provide automatically register and unregister Coverlib.dll on the fly under HKCU. So if using those you are already sorted.

3. If using the command line, NCover 1.5.7 now offers a //reg option. This will do the same as the tasks above of registering and unregistering on the fly.

4. You could invoke regsvr32 on it as part of your script. I suggest you unregister it as well afterwards in case you have multiple NCover versions on your machine to prevent any later confusion.

NCover With TestDriven.NET

I got myself caught out with this little gotcha recently and I'm sure I won't be the last!

As you likely know the excellent TestDriven.Net add-in by Jamie Cansdale includes a copy of (currently) NCover 1.3.3 and NCover 1.5.7 bundled with it. What you probably don't know is under which scenarios it runs which version of NCover and where this can go wrong.

The first thing TestDriven.Net does is check the registry to see if you have installed NCover yourself using the MSI installer. If there isn't then it knows to use one of the versions it has installed. If you have .NET 2.0 installed on your machine it will use the 1.5.x version, otherwise it will use NCover 1.3.3.

If however you do have NCover installed from the MSI, then TestDriven.NET assumes that you want to use that version. Jamie's rationale for this is simple - if you ended up with later versions of NCover on your machine than that supplied with TestDriven.NET then it should use that over it's own.

Where this can go wrong as it did for me is if for some reason you have unregistered NCover in that folder. TestDriven.NET makes the reasonable assumption that if you installed it and left it there then you have it registered there too. However as I dabble with testing and supporting multiple NCover versions all over my drives I had manually unregistered it without remembering to uninstall it. That mistake will then lead to error messages from TestDriven.NET about "Unable to create a coverage report". Either fully uninstall that NCover installation or register CoverLib.dll again in that folder to fix this. My thanks to Jamie for his excellent support!

TypeMock And NCover NAnt/MSBuild Tasks

TypeMock is a very powerful mock objects framework which no doubt some of you are using. Assuming you have purchased the commercial version then you will likely want to be running your tests with code coverage using NCover.

The one gotcha with this is that a requirement of the .NET profiling API is that there can only be one profiler callback registered on a machine when it runs. TypeMock takes care of this by managing the registry itself. However if you use my NAnt/MSBuild tasks then by default they want to "undo" the work of TypeMock by registering NCover, causing a problem.

The solution is available from the 1.3.6.11 build of my tasks in NCoverExplorer.Extras, the latest of which is available here. By adding a registerProfiler="false" attribute to your NAnt task or equivalent for MSBuild the default behaviour of the tasks to register in HKCU is turned off and control is able to be maintained by TypeMock.

That's enough for today. Part 2 will cover the mysterious blank coverage.xml file. Feedback/corrections welcomed - if you have an NCover problem your best bet is to head to the NCover forums.

Filed in:

24 Comments:

At April 19, 2007 7:38 am, Blogger GraemeF said...

Great stuff! I've been caught out by the first problem several times.

 
At May 30, 2007 5:35 am, Blogger Paul Duran said...

Hi,

i'm not sure if you will see this post since your blog entry is a month old but I thought i should add mention what my problem was with respect to the 'profiler connection not established' issue.

In my nant script, i was calling ncover as such:

<ncover
program="tools\NCover\NCover.Console.exe"
commandLineExe="tools\nunit\nunit-console.exe"
...
>

And when i checked the registry, the InProcServer32 entry was being registered as:

tools\NCover\CoverLib.dll

When i changed the program='...' to:
program="${path::get-full-path('tools\NCover\NCover.Console.exe')}"

it registers the dll correctly and ncover works successfully.

It is a minor change that i had to make but it could be avoided if the ncover nant task registers the dll using the full path to the dll.

cheers,
Paul.

 
At May 30, 2007 5:20 pm, Anonymous Anonymous said...

I think there is a problem with the method involving registering/unregistering coverlib on the fly (with the //reg switch).
When several concurrent instances of NCover are running, the first to exit will unregister the dll, and the second one will try to unregister it again, which causes an uncatched exception and crashes NCover (and displays a messagebox, a most unfortunate side effect).

One solution would be for NCover to unregister ncoverlib only if it's still registered, or to properly catch the exception...

 
At May 30, 2007 7:07 pm, Blogger kiwidude said...

Fatal - all comments get e-mailed to me no matter how old the entry. I will have a look at the task to see what can be done about using a relative path. It should cope with it but the fact it doesn't for you implies a problem. I will let you know if it is something I find to fix...

Yann - your suggestion about a "reference counting" implementation is something I added to my ncover tasks fairly recently. This does exactly what you describe. Of course if you run ncover directly using it's //reg switch instead then similar logic would have to exist inside ncover. Give the NAnt/MSBuild tasks a go and let me know how you get on...

 
At June 02, 2007 6:18 pm, Blogger kiwidude said...

For anyone reading - the relative path issue has been fixed in build 1.3.6.15 of the NCoverExplorer.NAntTasks.dll.

 
At June 17, 2007 9:31 pm, Blogger Martin Bayly said...

I've been having similar problems when running my build via CruiseControl as a service on Windows Server 2003.

I tried a lot of the solutions discussed here but none of them seemed to work.

The only way I could get it to work when running as a service was to either:

1. Install NCover directly on the build machine.

OR

2. Run the CC.NET service as the build machine Administrator user. By default it runs as LocalSystem.

I'm running:

NCover-1.5.8
NCoverExplorer.Extras-1.3.6.15

 
At June 17, 2007 11:51 pm, Blogger kiwidude said...

Martini,

Yes that is expected behaviour. The trick of temporarily simulating the COM registration (either via the NCover task or //reg arguments) works by writing a key under HKEY_CURRENT_USER - this trick won't work when you are running as the local system account. However as you have found out either running the service as a "real" user account or using regsvr32 (which registers under HKLM) will do the trick.

 
At August 01, 2007 11:03 am, Anonymous Anonymous said...

Hi

I had been struggling with getting ncover to play nicely with mstest, using kiwidude's nice nant build tasks. I kept coming back with an empty coverage.xml file.

It finally clicked that mstest.exe spawns a new process VSTestHost.exe to actually perform the tests. After i put the profiledProcessModule="VSTestHost.exe" attribute on the ncover nant task, everything is fine.

cheers
-Mark

 
At September 10, 2007 5:23 pm, Blogger Tim said...

So it's been 6 months since the last release - when are you planning another drop (hopefully with the iis timeout configurable...)

 
At September 10, 2007 10:07 pm, Blogger kiwidude said...

Hi Tim,

NCoverExplorer 1.4 is in beta now and I need to push a new build up to make it a final release.

NCover 2.0/NCoverExplorer 2.0 is also in the final stages of development. No doubt Peter will make the announcements when he is ready to talk about it. This will include configurable IIS timeouts...

Grant.

 
At November 13, 2007 9:25 pm, Anonymous Anonymous said...

I tried to re-register the coverlib.dll but i still get the issue "Profiler connection not established". I registered thru admin acces..

 
At November 13, 2007 9:55 pm, Blogger kiwidude said...

Anonymous - I suggest you post your question in the forums at NCover.com with more details about versions of NCover, OS etc. Good luck!

 
At March 14, 2008 4:01 pm, Anonymous Anonymous said...

Love this thread!
Is there a way to support specifying the Symbol Search Policy (//ssp)?

-su

 
At March 16, 2008 7:04 pm, Blogger kiwidude said...

Glad you found it helpful. I would suggest you should direct any questions to the ncover.com forums, but yes, you can use the //ssp argument in NCover 1.5.8 to control the policy.

 
At September 05, 2008 12:59 pm, Anonymous Anonymous said...

You are a legend!! I've spent a day just trying to get NCover set up and it just kept writing empty Coverage.xml files. All I needed was /noshadow, yet this is the only place where it's mentioned. Works a treat, nice one, thank you!

 
At November 14, 2008 4:30 pm, Anonymous Anonymous said...

Just want to confirm the last comment; this is a legendary post!!

Thanks a million Grant!

 
At March 26, 2009 4:57 am, Blogger Kevin said...

Awesome dude. Very Very helpful!

 
At August 20, 2009 8:27 am, Anonymous Matt Chatterley said...

Thanks Grant; this is about the 8th time this thread has saved me a load of mucking about. Always forget this one.

If anyone gets an error from DllRegisterServer (0x80070005) when trying to run regsvr32 against CoverLib.dll in Vista/Win2008/Win7/etc, then you need to open an elevated command prompt - right click, run as admin!

 
At October 02, 2009 5:10 pm, Anonymous Anonymous said...

Thanks for sharing that tip on TestDriven.Net and NCover. It was the easiest way to get this going again.

 
At February 17, 2010 7:23 pm, Anonymous Anthony Bouch said...

I was also getting this error with when I mistakenly ran NCover.Console.exe v1.5.8 against xunit.console.exe - the 64bit flavor and not xunit.console.x86.exe.

 
At February 07, 2011 12:51 pm, Anonymous Ian said...

If you have found this thread because you are trying to get NCover 1.5.8 to work with .NET 4 then the following should fix this error:

Open a command prompt and type the following
set COMPLUS_ProfAPI_ProfilerCompatibilitySetting=EnableV2Profiler

This instructs the .NET 4 CLR to load the .NET Framework 2.0 Profiler.

For more information see: http://msdn.microsoft.com/en-us/library/dd778910.aspx

 
At February 08, 2011 8:43 am, Blogger Unknown said...

for those trying to get it to work with NUnit and .net 4.0 I found that adding this to the NUnit.console-x86.exe.config forced NUnit into the .NET 4.0 runtime and allowed the old version of the profiler to be supported:

< configuration>
< startup useLegacyV2RuntimeActivationPolicy="true">
< supportedRuntime version="v4.0.30319"/>
< /startup>
< /configuration>

more details are here: http://stackoverflow.com/questions/4921443/force-ncover-1-5-8-to-use-v4-framework-like-testdriven-net-does

 
At September 29, 2011 9:34 pm, Blogger Brian said...

I'm using NCover 1.5.8 with a .Net 4.0 project. I've tried manually registering CoverLib.dll, running "set COMPLUS_ProfAPI_ProfilerCompatibilitySetting=EnableV2", adding useLegacyV2RuntimeActivationPolicy="true" and to the nunit-console-x86.exe.config and even targeting the 3.5 framework instead of 4.0 in my projects. Nothing has worked. I still get the "Profiled process terminated. Profiler connection not established." message. Any other ideas? Thanks! -Brian

 
At October 01, 2011 11:14 am, Blogger kiwidude said...

@Brian and others - please use the forums at NCover.com for any queries, there are experts there who can help. I am not surprised that versions of .NET beyond that of the free version of NCover can have issues given the very low level the coverage profiler operates at - the commercial product of course does not suffer from these issues if you can convince your boss to buy it.

 

Post a Comment

<< Home