Welcome to MSDN Blogs Sign in | Join | Help

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:

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

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

 

 

 

Published Friday, October 20, 2006 10:50 PM by thottams@microsoft.com

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: Managed Debugging Assistants (MDA's)

That is great stuff! For those of us doing WinForms and/or Interop, MDAs look like "just what the doctor ordered". Thanks for making this kind of information more widely known.

Tuesday, October 31, 2006 10:27 PM by SteveC

# re: Managed Debugging Assistants (MDA's)

I am glad this was useful. It will be nice to know your experience after your tunred on MDA's in your application and if it was helpful in any form.

Thursday, November 02, 2006 9:17 PM by Thottam Sriram

# re: Managed Debugging Assistants (MDA's)

It provides very useful information. Thanks for doing this.

Friday, December 01, 2006 5:40 PM by Tao Wang

# re: Managed Debugging Assistants (MDA's)

Thanks Tao. I am glad this was useful.

Tuesday, December 05, 2006 12:37 PM by Thottam Sriram

# re: Managed Debugging Assistants (MDA's)

Thursday, March 29, 2007 6:14 AM by eople

# re: Managed Debugging Assistants (MDA's)

Great - very usefull - very interesting info but it still doesn't work.

1. MDA is switched off by Debug-options

very well no brake anymore

BUT

(sample from Microsoft)

Private Declare Function GetVolumeInformation _

 Lib "kernel32" Alias "GetVolumeInformationA" ( _

 ByVal RootPathName As String, _

 ByVal VolumeNameBuffer As String, _

 ByVal VolumeNameSize As Long, _

 ByRef VolumeSerialNumber As Long, _

 ByRef MaximumComponentLength As Long, _

 ByRef FileSystemFlags As Long, _

 ByVal FileSystemNameBuffer As String, _

 ByVal FileSystemNameSize As Long _

 ) As Long

' --- Sourcecode

Private Function GetSerialNumber(ByVal Drive As String) As Long

' Liefert die Seriennummer eines Datenträgers zurück, dessen

' Laufwerksbuchstabe übergeben wird. Auch die Übergabe einer

' vollständigen Pfadangabe zu einem Verzeichnis oder einer Datei

' auf dem Datenträger ist möglich. Bitte beachten Sie, dass eine

' Seriennummer unter VB als negative Zahl erscheinen kann, da der

' Datentyp Long vorzeichenbehaftet ist. Wählen Sie für eine Dar-

' stellung der Seriennummer eine Darstellung als Hexadezimalzahl.

Dim lDummy As Long

 ' Hauptverzeichnis-Angabe aus dem übergebenen Parameter erstellen

 If Len(Drive)>0 Then 'small modification here

   If Left$(Drive, 2) <> "\\" Then

     Drive = Left$(LTrim$(Drive), 1) & ":\"

   End If

 End If

 ' Die Seriennummer des Datenträgers in diesem Laufwerk ermitteln

 GetVolumeInformation Drive, vbNullString, _

                      0, GetSerialNumber, _

                      lDummy, lDummy, _

                      vbNullString, 0

End Function

Private Function GetSerialNumberString(ByVal Drive As String) As String

' Liefert die hexadezimale Darstellung  der Seriennummer eines Datenträgers

' zurück, dessen Laufwerksbuchstabe übergeben wird. Auch die Übergabe einer

' vollständigen Pfadangabe zu einem Verzeichnis oder einer Datei

' auf dem Datenträger ist möglich.

 GetSerialNumberString = Hex$(GetSerialNumber(Drive))

End Function

Delivers at anytime &H0

may be the MDA is right ? is there a problem

to get in touch with the kernel32.dll ???

Can You help ?

Thanks in advance

tb@optimal-process.de

Saturday, May 12, 2007 6:21 PM by Thomas Bernhard

# re: Managed Debugging Assistants (MDA's)

Try using the following signature for GetVolumeInformation

Imports System.Runtime.InteropServices

Public Declare Function GetVolumeInformation _

   Lib "kernel32" Alias "GetVolumeInformationA" ( _

   <MarshalAsAttribute(UnmanagedType.LPStr)> ByVal lpRootPathName As String, _

   ByVal lpVolumeNameBuffer As System.IntPtr, _

   ByVal nVolumeNameSize As UInteger, _

   ByRef lpVolumeSerialNumber As UInteger, _

   ByRef lpMaximumComponentLength As UInteger, _

   ByRef lpFileSystemFlags As UInteger, _

   ByVal lpFileSystemNameBuffer As System.IntPtr, _

   ByVal nFileSystemNameSize As UInteger _

   ) As <MarshalAsAttribute(UnmanagedType.Bool)> Boolean

Monday, June 11, 2007 7:00 PM by dmilirud

# re: Managed Debugging Assistants (MDA's)

Actually even better is to use StringBuilder for the 2nd and 7th parameters:

 Private Declare Function GetVolumeInformation _

   Lib "kernel32" Alias "GetVolumeInformationA" ( _

   <MarshalAsAttribute(UnmanagedType.LPStr)> ByVal lpRootPathName As String, _

   ByVal lpVolumeNameBuffer As StringBuilder, _

   ByVal nVolumeNameSize As UInteger, _

   ByRef lpVolumeSerialNumber As UInteger, _

   ByRef lpMaximumComponentLength As UInteger, _

   ByRef lpFileSystemFlags As UInteger, _

   ByVal lpFileSystemNameBuffer As StringBuilder, _

   ByVal nFileSystemNameSize As UInteger _

   ) As <MarshalAsAttribute(UnmanagedType.Bool)> Boolean

Tuesday, June 12, 2007 2:18 PM by dmilirud

# Good site

<a href= http://index7.riesxd.com >intetin</a> <a href= http://index3.riesxd.com >t mobil cell phones plans</a> <a href= http://index4.riesxd.com >mfc42.dll islinkedto missing export kernel32.dll</a> <a href= http://index2.riesxd.com >deastisdesigns</a> <a href= http://index8.riesxd.com >triamcindlone cream</a>

Wednesday, August 13, 2008 12:56 AM by balabo_ak

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
 
Page view tracker