Debugging API Changes in the .NET Framework 2.0
This topic explains changes in the .NET Framework version 2.0 that you should consider when you use the common language runtime (CLR) debugging API.
API Changes
CorDebug is no longer a coclass. Instead of co-creating it, use the CreateDebuggingInterfaceFromVersion global static function in the hosting API. The debugger version should be one of the constants from the CorDebugInterfaceVersion enumeration in CorDebug.idl. (Use the CorDebugVersion_2_0 constant if your debugger supports the .NET Framework 2.0.) Use the GetVersionFromProcess global static function in the hosting API to get the debuggee version for a running process. Or you can use the GetRequestedRuntimeVersion global static function in the hosting API to get a best guess for the version that will be loaded for a given .exe file on disk, or ask the user to pick a version of the runtime. (You can use the GetRequestedRuntimeInfo global static function in the hosting API to determine whether the user-provided string is a valid version.) All these functions are defined in MSCorEE.idl.
A debugger must implement the ICorDebugManagedCallback2 interface in order to be recognized as a .NET Framework 2.0-capable debugger.
ICorDebugEnum return values are COM-compliant in the .NET Framework 2.0.
New ICorDebugInternalFrame objects may appear in stack traces where the runtime has inserted a special frame to accomplish some task. These frames will not respond to a QueryInterface query for either the ICorDebugNativeFrame or ICorDebugILFrame interface.
The time-out to the ICorDebugController::Stop method is ignored.
You may use the ICorDebugModule::EnableJITDebugging method only when the module is first loaded. If this method is used in a ModuleLoad callback that is issued as part of an attach operation, it will fail. (This restriction ensures that the module has consistent code for all its functions.)
The native code for a given function in the .NET Framework might not be in a single contiguous block of memory. As a result, debuggers should no longer use the GetAddress, GetSize, and GetCode methods of the ICorDebugCode interface. Instead, they should use ICorDebugCode2::GetCodeChunks and ICorDebugProcess::ReadMemory.
Mixed-mode debuggers must set unmanaged breakpoints by using the new ICorDebugProcess2::SetUnmanagedBreakpoint method.
The native thread exit debug event is out-of-band in the .NET Framework 2.0.
Objects in the debugging API are invalidated more aggressively. If an operation that succeeded in the .NET Framework 1.0 or 1.1 returns CORDBG_E_OBJECT_NEUTERED in the .NET Framework 2.0, the interface upon which the operation was performed has exceeded its lifetime and should be re-obtained. The values that were obtained from the operations in the .NET Framework 1.0 and 1.1 might not have been correct.
Generics
The introduction of generics in the .NET Framework 2.0 breaks many assumptions a debugger might have made in earlier versions. Debuggers should move to using the following generics-aware forms of ICorDebug functions:
Use ICorDebugType::GetStaticFieldValue instead of its counterpart in the ICorDebugClass interface.
Use ICorDebugEval2::CallParameterizedFunction, ICorDebugEval2::NewParameterizedObject, ICorDebugEval2::NewParameterizedObjectNoConstructor, ICorDebugEval2::NewParameterizedArray, and ICorDebugEval2::CreateValueForType instead of their counterparts in the ICorDebugEval interface.
Use ICorDebugFunction2::EnumerateNativeCode instead of ICorDebugFunction::GetNativeCode.