Managed Debugging Assistants (MDA's)

When I read through the responses for the questionnaire below I saw that many users were not aware of MDA’s and that drove the topic for this post. I had written a small sample for a simple MDA which I thought that I will share with everyone.

MDA’s can help you diagnose problems that you might not know about normally. These are like advanced diagnostic messages that tell you what is going wrong in your application. There are many ways to turn MDA’s on and off. Let us look in to them here.

Consider the following source code (sample.cs):

using System;

using System.Diagnostics;

using System.Runtime.InteropServices;

public class Program {

    public static void Main() {

        Beep(5,5);

    }

    [DllImport("kernel32.dll", SetLastError=true)]

    [return: MarshalAs(UnmanagedType.Bool)]

    internal static extern bool Beep(long frequency, long duration);

}

Let us compile this code and execute it :- csc sample.cs /debug

This runs without any errors. If you enable MDA’s then it will let you know that the marshalling for Beep is wrong as it takes two DROWD and hence the parameter should be “int” instead of “long”. How do you catch this error is the question? MDA’s come in handy for this. Here is how you would do it with MDA’s.

Step-1: Turning on MDA’s

There is a global registry key which is used to turn on MDA’s.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]

"MDA"="1"

Step – 2: Selecting individual MDA’s as required:

Now you can select individual MDA’s that you want in three different ways as mentioned below

1. Through an exe.mda.config file

2. Through environment variable

3. Through Exceptions in Visual Studio

1. Enabling MDA’s through sample.exe.mda.config file

Let us produce sample.exe.mda.config file as below:

 

<mdaConfig>

  <assistants>

    <pInvokeStackImbalance enable="true"/>

  </assistants>

</mdaConfig>

This enables the pInvokeStackImbalance MDA which will fire off when it finds irregularities in marshalling.

2. Enabling MDA’s through environment variables

Set the environment variable COMPLUS_MDA as mentioned below.

COMPLUS_MDA= pInvokeStackImbalance

3. Enabling MDA’s from Visual Studio

You can enable MDA’s from Visual Studio by going to Debug-Exceptions-Managing Debugging Assistants and selecting the MDA’s that are of interest to you.

Let us enable the pInvokeStackImbalance MDA using the sample.exe.mda.config option and run the above executable again. This time you get an error message as follows:

Managed Debugging Assistant 'PInvokeStackImbalance' has detected a problem in sample.exe.

Additional Information: A call to PInvoke function 'sample!Program::Beep' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature

This is pretty good information that you can use to correct the signature of the pInvoke from long, long to int,int and re run the code. This time the MDA does not fire up. Your marshalling should be correct then! There is good information about MDA’s at the following locations and I recommend everyone to read them.

 

The msdn article at MDA walks through the same example that I have here with excellent details. I strongly urge reading through that. I read it and it is extremely useful.

Other references are:

https://blogs.msdn.com/jmstall/archive/2005/11/10/introducing-mdas.aspx

https://msdn2.microsoft.com/en-us/library/d21c150d.aspx