Thursday, 26 December 2013

The process was terminated due to an internal error in the .NET Runtime


If your .NET process crashes unexpectedly with the following message in the Event Log: "The process was terminated due to an internal error in the .NET Runtime...", there are a few things we can do to investigate it. Unfortunately, the exception already occurred, the process crashed and there is nothing interesting in the logs. First of all we'd like to find out what happens that causes to this crash and where in the code it happens. In order to do this we can start by downloading and installing Debug Diagnostic tool. Then configuring it in the following matter:

Select Crash, because that's what we're investigating:


Select a specific process, because we know what process crashes:


Select the process you want to investigate:


Select "Full Userdump":

With the DebugDiag running in the background, reproduce the scenario that causes the initial process termination. When the process crashes, we'll find in DebugDiag log folder with a few files. The log folder is
C:\Program Files\DebugDiag\Logs
The interesting file is the one with .DMP extension. Double click it and it will be opened in DeBug Diagnostic Analysis. It will convert the DMP file to HTML report and will open it in IE. Yes, yes, IE, even if your favorite browser is Chrome. Ok, ok, just give me the call stack

We are looking for any errors, crashes in that HTML log. In my case I found "access violation" exception and call stack of the exception. Surprisingly, the call stack is pretty obvious code. It accesses a property which is null, so I would expect a NullReferenceException. But it was access violation. What is more interesting, is that that piece of code is surrounded by try/catch block.

Starting from .NET 4.0, access violation exceptions and similar are not thrown in the regular way. They just terminate the process and are not caught in try block. But there are two still to catch them:
  • 1. Using attribute HandleProcessCorruptedStateExceptions on the suspicious method
  • 2. Using <legacyCorruptedStateExceptionsPolicy enabled="true" />
Below code demonstrates how to apply HandleProcessCorruptedStateExceptions attribute on suspicious method. It enables catching the access violation exception.
 

    internal class Program
    {
        private static void Main(string[] args)
        {
            var crashingThread = new Thread(CrashingThread);
            crashingThread.Start();

            Console.ReadKey();
        }

        [HandleProcessCorruptedStateExceptions]
        private static void CrashingThread()
        {
            try
            {
                CrashMe();
            }
            catch (Exception exception)
            {
                Console.WriteLine("I caught access violation");
                Console.WriteLine(exception.ToString());
            }
        }

        private static unsafe void CrashMe()
        {
            unsafe
            {
                int read = *((int*) long.MaxValue - 8);
            }
        }
    }



A few last notes about that attribute:
It can be applied on any level on the call stack of the suspicious code. Even on the Main method. However it won't work if you apply the attribute on the main method, but the exception occurs in another thread. It should be applied on the method that is on the crashing thread!

Please note, that it is not recommended to leave that attribute in production code. It should be used only for debugging purposes.

Enjoy your debugging!

Wednesday, 11 December 2013

BizArk.Core 2.0.9 was pushed to NuGet

Bizark.Core 2.0.9 was pushed to NuGet

Release notes:
9151 Empty argument prefix does not work and does not

Example:
 
[CmdLineOptions(ArgumentPrefix = "")]
internal class MyCmdLineObject: CmdLineObject
{
     [CmdLineArg]
     public string Name { get; set; }
}
Can be used like this from command-line
MyConsoleApplication.exe Name Boris

In conjunction with ArgumentDelimiter:
 
[CmdLineOptions(ArgumentPrefix = "", ArgumentDelimiter='=')]
internal class MyCmdLineObject : CmdLineObject
{
     [CmdLineArg]
     public string Name { get; set; }
}
From command line
MyConsoleApplication.exe Name=Boris

Also supports string surrounded by double quotes:
 
[CmdLineOptions(ArgumentPrefix = "", ArgumentDelimiter='=')]
internal class MyCmdLineObject : CmdLineObject
{
     [CmdLineArg]
     public string Path { get; set; }
}
MyConsoleApplication.exe Path="C:\Program Files (x86)\Microsoft.NET\"
The value of Path will be @"C:\Program Files (x86)\Microsoft.NET\" without the leading and ending double quotes

Get from nuget:

PM> Install-Package BizArk.Core

Wednesday, 4 December 2013

Goodbye Autofac

Autofac is one of my favorite IoC containers, due to its fluent, easy-to-learn syntax and great performance. However recently it let me down in some occasions and I had to get rid of it in the main project, I am working on. But let me explain it from the beginning.

Since Autofac 3.0, it is compiled against Portable .NET Framework. It is a subset of the usual .NET Framework, which runs on various devices and platforms. Such as Silverlight, mobile etc. The portable framework version number is 2.0.5.0. So far, so good. It worked well in my project with .NET Framework 4.5. But...

1. When we tried to obfuscate Autofac.dll using Dotfuscator version 4.8, it complained that mscorlib.dll version 2.0.5.0 cannot be found. Although it exists in the corresponding directory under C:\Windows\Microsoft.NET\Framework . Travis Illig suggested me to upgrade the Dotfuscator to latest version, which would definitely resolve the problem.

From Dotfuscator v 4.9 release notes:
  • Using String Encryption on Portable Class Libraries will no longer cause Windows Store apps to fail certification.
http://www.preemptive.com/support/dotfuscator-support/dotfuscator-pro-change-log/464

Unfortunately, upgrading Dotfuscator means purchasing a new license, which is pretty expensive. We managed to overcome this problem by putting mscorlib.dll v2.0.5.0 in one of the internal directories. Dotfuscator scans directories and managed to find it successfully.

2. The second problem appeared when we started testing the product on clean machines. We get the following exception, despite the fact that Portable Framework exists on the machine:

Could not load file or assembly 'System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes' or one of its dependencies. 

It happens as a result of Microsoft Known Bug KB2468871. It was fixed by the Redmond folks, but the relevant update is not installed on the machine.

So it means, that in order to use Autofac we have to required from our customers to install Windows Updates. Sometimes it might cause issues with corporate customers, that have strict policy regarding machine updates. It was decided that we'll stop using Autofac in this major project and will switch to something less "sensitive".

Nevertheless, we still use Autofac in many other internal projects. So it is not a real "Goodbye"




Wednesday, 13 November 2013

Opt in and opt out using Autofac IoC container

I am a big fan of dependency injection and inversion of control. I strive to use these techniques in almost every project I am involved with. Usually when I develop the project from the ground, the whole design is ready for automatic types scanning and auto wiring. So it is very easy to wire them up using a short piece of code. All the examples in this post will be using Autofac - the addictive IoC container.
 
public IContainer Initialize()
{
    var builder = new ContainerBuilder();
    builder.RegisterAssemblyTypes(GetType().Assembly).AsImplementedInterfaces();
    return builder.Build();
}

But sometimes, I need to prevent some classes from being registered, for example, the instance need to be created in run time with specific context parameters. In this case I use the opt-out, i.e. register all the types except those having a custom attribute:
 
[AttributeUsage(AttributeTargets.Class)]
public class DontRegisterInContainerAttribute : Attribute
{

}

public IContainer Initialize()
{
    var builder = new ContainerBuilder();
    builder.RegisterAssemblyTypes(GetType().Assembly)
        .Where(t => !t.HasAttribute<DontRegisterInContainerAttribute>())
        .AsImplementedInterfaces();
    return builder.Build();
}
In order to use the attribute in this syntax, I am using an extension method:
 
public static class TypeExtensions
{
    public static bool HasAttribute<T>(this Type @this)
    {
        return @this.GetCustomAttributes(typeof (T), false).Any();
    }
}

In some projects, when I am modifying existing code, which is not "IoC-ready", I need to register only a few classes. Hopefully their number will increase in the future. But currently what I am actually want is to type the container: register only these classes, without actually listing them or assume they reside in some namespace or have something in their name. In such cases I use the opposite:
 
public IContainer Initialize()
{
    var builder = new ContainerBuilder();
    builder.RegisterAssemblyTypes(GetType().Assembly)
        .Where(t => t.HasAttribute<RegisterInContainerAttribute>())
        .AsImplementedInterfaces();
    return builder.Build();
}

With the corresponding custom attribute:
 
[AttributeUsage(AttributeTargets.Class)]
public class RegisterInContainerAttribute : Attribute
{
         
}

Using this method of registering only types marked with the attribute also makes the code clearer to co-workers, who might look up for usages of the attribute and find out what classes are registered in the container. In case they are not familiar with Agent Mulder Resharper plugin.


Thursday, 24 October 2013

BizArk documentation on Console application

It seems that the best documentation is "single page" with code snippets. Projects with such kind of documentation are easy to understand and to use. I've just added such documentation to BizArk project.