Often an application will give you a generic error message like a FileLoadException when something goes wrong. Often you can fix the problem if you know what exactly went wrong. I’ve come across a dotNet program that gave me a generic error. While investigating the error with WinDBG I came across a more descriptive message that enabled me to fix the problem. In this post I describe the steps I took to diagnose the problem and solve it.
Please note: this post describes a specific problem and the exact method may not work for every application but the general method should apply to most dotNet applications.
An application is crashing during startup with the following message:
The message itself isn’t very useful to troubleshoot the crash. The Windows eventlog is a little more helpful with the following error:
While the logged error does point in the right direction it doesn’t show what file failed to load or why the file failed to load. The application itself does not log what file failed to load or why the file failed to load either. A ProcMon log doesn’t reveal any access denied or file not found issues. More specific exception information can be obtained using WinDBG, part of the Debugging Tools for Windows.
Configure the symbol path to point to the Microsoft symbol server. To do this either go to the File menu > Symbol File Path and configure the path as follows:
This tells WinDBG to retrieve the required symbols from http://msdl.microsoft.com/download/symbols and put them in D:\localsymbols.
There are several alternative ways to configure symbols, including downloading the symbols from Microsoft as a separate package. Downloading the symbols as a separate package can be useful when your debugging system doesn’t have internet access. More information about setting the symbol path can be found here.
The actual debugging
Go to File > Open Executable and select the executable you want to debug. The application will start loading several assemblies and hit its first breakpoint.
This breakpoint is caused by attaching the debugger to the executable and can be ignored. Continue debugging by pressing F5. The next exception that stops the program is a second chance exception. This means the application had the chance to handle the exception but didn’t, more information about first and second chance exceptions can be found here. The exception is a CLR (Common Language Runtime, part of the .NET framework) exception. By default WinDBG doesn’t know how to handle CLR exceptions. To make WinDBG understand CLR exceptions load a helper DLL clr.dll. Use the following command to load the dll:
.loadby sos clr
Loading clr.dll enables a few useful functions like !PrintException (or !pe for ease of typing). The !pe command shows the most recent exception.
The actual message that comes with the exception clearly shows the cause of the problem. Looking the message up on Google points me in the direction of this page.
As mentioned on the above page adding the useLegacyV2RuntimeActivationPolicy attribute to the startup element of the applications config file solved the issue. Below is a sample config file with the attribute added.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0" /> </startup>
I’ve used this blogpost to help with the CLR debugging.