Diagnose Errors with Managed Debugging Assistants
Note
This article is specific to .NET Framework. It doesn't apply to newer implementations of .NET, including .NET 6 and later versions.
Managed debugging assistants (MDAs) are debugging aids that work with the common language runtime (CLR) to provide information on runtime state. The assistants generate informational messages about runtime events that you cannot otherwise trap. You can use MDAs to isolate hard-to-find application bugs that occur when transitioning between managed and unmanaged code.
You can enable or disable all MDAs by adding a key to the Windows registry or by setting an environment variable. You can enable specific MDAs by using application configuration settings. You can set additional configuration settings for some individual MDAs in the application's configuration file. Because these configuration files are parsed when the runtime is loaded, you must enable the MDA before the managed application starts. You cannot enable it for applications that have already started.
The following table lists the MDAs that ship with .NET Framework:
By default, the .NET Framework activates a subset of MDAs for all managed debuggers. You can view the default set in Visual Studio by choosing Windows > Exception Settings on the Debug menu, and then expanding the Managed Debugging Assistants list.
Enable and Disable MDAs
You can enable and disable MDAs by using a registry key, an environment variable, and application configuration settings. You must enable either the registry key or the environment variable to use the application configuration settings.
Tip
Instead of disabling MDAs, you can prevent Visual Studio from displaying the MDA dialog box whenever an MDA notification is received. To do that, choose Windows > Exception Settings on the Debug menu, expand the Managed Debugging Assistants list, and then select or clear the Break When Thrown check box for the individual MDA.
Registry Key
To enable MDAs, add the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\MDA subkey (type REG_SZ, value 1) in the Windows registry. Copy the following example into a text file named MDAEnable.reg. Open the Windows Registry Editor (RegEdit.exe), and from the File menu choose Import. Select the MDAEnable.reg file to enable MDAs on that computer. Setting the subkey to string value of 1 (not DWORD value of 1) enables the reading of MDA settings from the ApplicationName.suffix.mda.config file. For example, the MDA configuration file for Notepad would be named notepad.exe.mda.config.
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
"MDA"="1"
If the computer is running a 32-bit application on a 64-bit operating system, then the MDA key should be set like the following:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework]
"MDA"="1"
See Application-Specific Configuration Settings for more information. The registry setting can be overridden by the COMPLUS_MDA
environment variable. See Environment Variable for more information.
To disable MDAs, set the MDA subkey to 0 (zero) using the Windows Registry Editor.
By default, some MDAs are enabled when you run an application that is attached to a debugger, even without adding the registry key. You can disable these assistants by running the MDADisable.reg file as described earlier in this section.
Environment Variable
MDA activation can also be controlled by the environment variable COMPLUS_MDA
, which overrides the registry key. The COMPLUS_MDA
string is a case-insensitive, semicolon-delimited list of MDA names or other special control strings. Starting under a managed or unmanaged debugger enables a set of MDAs by default. This is done by implicitly prepending the semicolon-delimited list of MDAs enabled by default under debuggers to the value of the environment variable or registry key. The special control strings are the following:
0
- Deactivates all MDAs.1
- Reads MDA settings from ApplicationName.mda.config.managedDebugger
- Explicitly activates all MDAs that are implicitly activated when a managed executable is started under a debugger.unmanagedDebugger
- Explicitly activates all MDAs that are implicitly activated when an unmanaged executable is started under a debugger.
If there are conflicting settings, the most recent settings override previous settings:
COMPLUS_MDA=0
disables all MDAs, including those implicitly enabled under a debugger.COMPLUS_MDA=gcUnmanagedToManaged
enablesgcUnmanagedToManaged
in addition to any MDAs that are implicitly enabled under a debugger.COMPLUS_MDA=0;gcUnmanagedToManaged
enablesgcUnmanagedToManaged
but disables MDAs that would otherwise be implicitly enabled under a debugger.
Application-Specific Configuration Settings
You can enable, disable, and configure some assistants individually in the MDA configuration file for the application. To enable the use of an application configuration file for configuring MDAs, either the MDA registry key or the COMPLUS_MDA
environment variable must be set. The application configuration file is typically located in the same directory as the application's executable (.exe) file. The file name takes the form ApplicationName.mda.config; for example, notepad.exe.mda.config. Assistants that are enabled in the application configuration file may have attributes or elements designed to control that assistant's behavior.
The following example shows how to enable and configure the marshaling:
<mdaConfig>
<assistants>
<marshaling>
<methodFilter>
<match name="*"/>
</methodFilter>
<fieldFilter>
<match name="*"/>
</fieldFilter>
</marshaling>
</assistants>
</mdaConfig>
The Marshaling
MDA emits information about the managed type that is being marshalled to an unmanaged type for each managed-to-unmanaged transition in the application. The Marshaling
MDA can also filter the names of the method and structure fields supplied in the methodFilter and fieldFilter child elements, respectively.
The following example shows how to enable multiple MDAs by using their default settings:
<mdaConfig>
<assistants>
<illegalPrepareConstrainedRegion />
<invalidCERCall />
<openGenericCERCall />
<virtualCERCall />
</assistants>
</mdaConfig>
Important
When you specify more than one assistant in a configuration file, you must list them in alphabetical order. For example, if you want to enable both the virtualCERCall
and the invalidCERCall
MDAs, you must add the <invalidCERCall />
entry before the <virtualCERCall />
entry. If the entries are not in alphabetical order, an unhandled invalid configuration file exception message is displayed.
MDA exceptions
When an MDA is enabled, it's active even when your code is not executing under a debugger. If an MDA event is raised when a debugger is not present, the event message is presented in an unhandled exception dialog box, although it is not an unhandled exception. To avoid the dialog box, remove the MDA-enabling settings when your code is not executing in a debugging environment.
When your code executes in the Visual Studio integrated development environment (IDE), you can avoid the exception dialog box that appears for specific MDA events. To do that, on the Debug menu, choose Windows > Exception Settings. In the Exception Settings window, expand the Managed Debugging Assistants list, and then clear the Break When Thrown check box for the individual MDA. You can also use this dialog box to enable the display of MDA exception dialog boxes.
MDA Output
MDA output is similar to the following example, which shows the output from the PInvokeStackImbalance
MDA:
A call to PInvoke function 'MDATest!MDATest.Program::StdCall' 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.