mirror of https://github.com/UMSKT/xpmgr.git
5662 lines
190 KiB
Plaintext
5662 lines
190 KiB
Plaintext
// ==++==
|
||
//
|
||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
//
|
||
// ==--==
|
||
/*****************************************************************************
|
||
** **
|
||
** Cordebug.idl - Common Language Runtime Debugging interfaces. **
|
||
** **
|
||
*****************************************************************************/
|
||
|
||
|
||
/* ------------------------------------------------------------------------- *
|
||
* Imported types
|
||
* ------------------------------------------------------------------------- */
|
||
|
||
#if !DEFINITIONS_FROM_NON_IMPORTABLE_PLACES
|
||
|
||
cpp_quote("#if 0")
|
||
|
||
import "unknwn.idl";
|
||
import "objidl.idl";
|
||
|
||
typedef UINT32 mdToken;
|
||
typedef mdToken mdModule;
|
||
typedef SIZE_T mdScope;
|
||
typedef mdToken mdTypeDef;
|
||
typedef mdToken mdSourceFile;
|
||
typedef mdToken mdMemberRef;
|
||
typedef mdToken mdMethodDef;
|
||
typedef mdToken mdFieldDef;
|
||
typedef mdToken mdSignature;
|
||
typedef ULONG CorElementType;
|
||
typedef SIZE_T PCCOR_SIGNATURE;
|
||
|
||
typedef SIZE_T LPDEBUG_EVENT;
|
||
|
||
typedef SIZE_T LPSTARTUPINFOW;
|
||
typedef SIZE_T LPPROCESS_INFORMATION;
|
||
|
||
|
||
cpp_quote("#endif")
|
||
|
||
typedef [wire_marshal(unsigned long)] void *HPROCESS;
|
||
typedef [wire_marshal(unsigned long)] void *HTHREAD;
|
||
|
||
typedef UINT64 TASKID;
|
||
typedef DWORD CONNID;
|
||
|
||
|
||
|
||
|
||
#endif
|
||
|
||
cpp_quote("#ifndef _COR_IL_MAP")
|
||
cpp_quote("#define _COR_IL_MAP")
|
||
|
||
// Note that this structure is also defined in CorProf.idl - PROPOGATE CHANGES
|
||
// BOTH WAYS, or this'll become a really insidious bug some day.
|
||
typedef struct _COR_IL_MAP
|
||
{
|
||
ULONG32 oldOffset; // Old IL offset relative to beginning of function
|
||
ULONG32 newOffset; // New IL offset relative to beginning of function
|
||
BOOL fAccurate; // TRUE if mapping is known to be good, FALSE otherwise
|
||
} COR_IL_MAP;
|
||
|
||
cpp_quote("#endif //_COR_IL_MAP")
|
||
|
||
cpp_quote("#ifndef _COR_DEBUG_IL_TO_NATIVE_MAP_")
|
||
cpp_quote("#define _COR_DEBUG_IL_TO_NATIVE_MAP_")
|
||
|
||
/* ICorDebugCode:: GetILToNativeMapping returns an array of
|
||
* COR_DEBUG_IL_TO_NATIVE_MAP structures. In order to convey that certain
|
||
* ranges of native instructions correspond to special regions of code (for
|
||
* example, the prolog), an entry in the array may have it's ilOffset field set
|
||
* to one of these values.
|
||
*/
|
||
typedef enum CorDebugIlToNativeMappingTypes
|
||
{
|
||
NO_MAPPING = -1,
|
||
PROLOG = -2,
|
||
EPILOG = -3
|
||
} CorDebugIlToNativeMappingTypes;
|
||
|
||
typedef struct COR_DEBUG_IL_TO_NATIVE_MAP
|
||
{
|
||
ULONG32 ilOffset;
|
||
ULONG32 nativeStartOffset;
|
||
ULONG32 nativeEndOffset;
|
||
} COR_DEBUG_IL_TO_NATIVE_MAP;
|
||
|
||
cpp_quote("#endif // _COR_DEBUG_IL_TO_NATIVE_MAP_")
|
||
|
||
cpp_quote("#define REMOTE_DEBUGGING_DLL_ENTRY L\"Software\\\\Microsoft\\\\.NETFramework\\\\Debugger\\\\ActivateRemoteDebugging\"")
|
||
|
||
|
||
typedef enum CorDebugJITCompilerFlags
|
||
{
|
||
CORDEBUG_JIT_DEFAULT = 0x1, // Track info, enable optimizations
|
||
CORDEBUG_JIT_DISABLE_OPTIMIZATION = 0x3, // Includes track info, disable opts,
|
||
CORDEBUG_JIT_ENABLE_ENC = 0x7 // Includes track & disable opt & Edit and Continue.
|
||
} CorDebugJITCompilerFlags;
|
||
|
||
typedef enum CorDebugJITCompilerFlagsDecprecated
|
||
{
|
||
CORDEBUG_JIT_TRACK_DEBUG_INFO = 0x1, // Use CORDEBUG_JIT_DEFAULT instead
|
||
} CorDebugJITCompilerFlagsDeprecated;
|
||
|
||
|
||
/* ------------------------------------------------------------------------- *
|
||
* Forward declarations
|
||
* ------------------------------------------------------------------------- */
|
||
#pragma warning(push)
|
||
#pragma warning(disable:28718) //Unable to annotate as this is not a local interface
|
||
|
||
interface ICorDebug;
|
||
|
||
interface ICorDebugController;
|
||
interface ICorDebugProcess;
|
||
interface ICorDebugProcess2;
|
||
interface ICorDebugAppDomain;
|
||
interface ICorDebugAssembly;
|
||
interface ICorDebugAssembly2;
|
||
interface ICorDebugBreakpoint;
|
||
interface ICorDebugFunctionBreakpoint;
|
||
interface ICorDebugModuleBreakpoint;
|
||
interface ICorDebugValueBreakpoint;
|
||
interface ICorDebugStepper;
|
||
interface ICorDebugEval;
|
||
interface ICorDebugEval2;
|
||
interface ICorDebugThread;
|
||
interface ICorDebugThread2;
|
||
interface ICorDebugThread3;
|
||
interface ICorDebugThread4;
|
||
interface ICorDebugStackWalk;
|
||
interface ICorDebugChain;
|
||
interface ICorDebugFrame;
|
||
interface ICorDebugILFrame;
|
||
interface ICorDebugInternalFrame;
|
||
interface ICorDebugInternalFrame2;
|
||
interface ICorDebugNativeFrame;
|
||
interface ICorDebugNativeFrame2;
|
||
interface ICorDebugRuntimeUnwindableFrame;
|
||
interface ICorDebugContext;
|
||
interface ICorDebugModule;
|
||
interface ICorDebugFunction;
|
||
interface ICorDebugFunction2;
|
||
interface ICorDebugCode;
|
||
interface ICorDebugClass;
|
||
interface ICorDebugType;
|
||
|
||
interface ICorDebugValue;
|
||
interface ICorDebugGenericValue;
|
||
interface ICorDebugReferenceValue;
|
||
interface ICorDebugHeapValue;
|
||
interface ICorDebugHeapValue2;
|
||
interface ICorDebugHeapValue3;
|
||
interface ICorDebugHandleValue;
|
||
interface ICorDebugObjectValue;
|
||
interface ICorDebugStringValue;
|
||
interface ICorDebugArrayValue;
|
||
|
||
interface ICorDebugEnum;
|
||
interface ICorDebugObjectEnum;
|
||
interface ICorDebugProcessEnum;
|
||
interface ICorDebugBreakpointEnum;
|
||
interface ICorDebugStepperEnum;
|
||
interface ICorDebugModuleEnum;
|
||
interface ICorDebugThreadEnum;
|
||
interface ICorDebugChainEnum;
|
||
interface ICorDebugTypeEnum;
|
||
interface ICorDebugCodeEnum;
|
||
interface ICorDebugFrameEnum;
|
||
interface ICorDebugValueEnum;
|
||
interface ICorDebugAppDomainEnum;
|
||
interface ICorDebugAssemblyEnum;
|
||
interface ICorDebugBlockingObjectEnum;
|
||
|
||
interface ICorDebugErrorInfoEnum;
|
||
interface ICorDebugMDA;
|
||
|
||
/* DEPRECATED */
|
||
interface ICorDebugEditAndContinueSnapshot;
|
||
/* DEPRECATED */
|
||
interface ICorDebugEditAndContinueErrorInfo;
|
||
|
||
#pragma warning(pop)
|
||
|
||
// All target addresses in ICorDebug are represented as 0-extended 64-bit integer values.
|
||
typedef ULONG64 CORDB_ADDRESS;
|
||
|
||
typedef ULONG64 CORDB_REGISTER;
|
||
|
||
typedef enum CorDebugBlockingReason {
|
||
BLOCKING_NONE = 0x0,
|
||
BLOCKING_MONITOR_CRITICAL_SECTION = 0x1,
|
||
BLOCKING_MONITOR_EVENT = 0x2
|
||
} CorDebugBlockingReason;
|
||
|
||
typedef struct CorDebugBlockingObject {
|
||
ICorDebugValue *pBlockingObject;
|
||
DWORD dwTimeout;
|
||
CorDebugBlockingReason blockingReason;
|
||
} CorDebugBlockingObject;
|
||
|
||
/*
|
||
* Callback interface for providing access to a particular target process. The
|
||
* debugging services will call functions on this interface to access memory
|
||
* and other data in the target process. The debugger client must implement
|
||
* this interface as appropriate for the particular target (for example, a live
|
||
* process or a memory dump). The DataTarget will only be invoked from within
|
||
* the implementation of other ICorDebug APIs (i.e. the debugger client has
|
||
* control over which thread it is invoked on, and when)
|
||
*
|
||
* Error HRESULTS returned by DataTarget APIs will propagate up and be returned
|
||
* by the active ICorDebug API call.
|
||
*
|
||
* The DataTarget implementation must always return up-to-date information
|
||
* about the target. The target process should be stopped (not changing
|
||
* in any way) while ICorDebug APIs (and hence DataTarget APIs) are being
|
||
* called. If the target is a live process and it's state changes,
|
||
* OpenVirtualProcess needs to be called again to provide a replacement
|
||
* ICorDebugProcess instance.
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(FE06DC28-49FB-4636-A4A3-E80DB4AE116C),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugDataTarget : IUnknown
|
||
{
|
||
/*
|
||
* GetPlatform returns the processor architecture and operating system on
|
||
* which the target process is (or was) running.
|
||
*
|
||
* This is used by ICorDebug to determine details of the target process
|
||
* such as its pointer size, address space layout, register set,
|
||
* instruction format, context layout, and calling conventions, etc.
|
||
* This platforms in this list are the only ones supported by this version
|
||
* of ICorDebug, but more may be added in future versions.
|
||
*
|
||
* Note that this may actually indicate the platform which is being
|
||
* emulated for the target, not the actual hardware in use. For example,
|
||
* a process running in the WOW on Windows x64 should use
|
||
* CORDB_PLATFORM_WINDOWS_X86.
|
||
*
|
||
* Implementations should be sure to describe what the platform of the
|
||
* target actually is, not just what the host expects it to be.
|
||
*
|
||
* This function must succeed. If it fails, the DataTarget is unusable.
|
||
*/
|
||
typedef enum CorDebugPlatform
|
||
{
|
||
CORDB_PLATFORM_WINDOWS_X86, // Windows on Intel x86
|
||
CORDB_PLATFORM_WINDOWS_AMD64, // Windows x64 (Amd64, Intel EM64T)
|
||
CORDB_PLATFORM_WINDOWS_IA64, // Windows on Intel IA-64
|
||
CORDB_PLATFORM_MAC_PPC, // MacOS on PowerPC
|
||
CORDB_PLATFORM_MAC_X86 // MacOS on Intel x86
|
||
} CorDebugPlatform;
|
||
|
||
HRESULT GetPlatform([out] CorDebugPlatform * pTargetPlatform);
|
||
|
||
/*
|
||
* ReadVirtual - Read virtual memory from the target process.
|
||
*
|
||
* Requests contiguous memory starting at the specified target address to
|
||
* be read from the target process into the supplied buffer. If at least
|
||
* the first byte (at the specified start address) can be read, the call
|
||
* should return success (to support efficient reading of data structures
|
||
* with self-describing length, like null-terminated strings).
|
||
*
|
||
* On success, the actual number of bytes read must be stored into
|
||
* pBytesRead.
|
||
*/
|
||
HRESULT ReadVirtual([in] CORDB_ADDRESS address,
|
||
[out, size_is(bytesRequested), length_is(*pBytesRead)] BYTE * pBuffer,
|
||
[in] ULONG32 bytesRequested,
|
||
[out] ULONG32 * pBytesRead);
|
||
|
||
/*
|
||
* GetThreadContext - Get the thread context (register values) for a thread.
|
||
*
|
||
* Requests the current thread context for the specified (operating-system
|
||
* defined) thread identifier. The size and format of the context record
|
||
* is platform dependant, and is determined by the result of the call to
|
||
* GetPlatform.
|
||
*
|
||
* The context flags specify, in a platform-dependent manor, which portions
|
||
* of the context should be read. contextSize specifies the size of the
|
||
* supplied buffer, but the function is free to not fill the whole buffer
|
||
* if it is possible to determine the actual size from the context.
|
||
*
|
||
* On Windows platforms, the buffer must be a CONTEXT structure appropriate
|
||
* for the machine type specified by GetPlatform. contextFlags has the
|
||
* same values as the ContextFlags field of CONTEXT.
|
||
*/
|
||
HRESULT GetThreadContext([in] DWORD dwThreadID,
|
||
[in] ULONG32 contextFlags,
|
||
[in] ULONG32 contextSize,
|
||
[out, size_is(contextSize)] BYTE * pContext);
|
||
};
|
||
|
||
|
||
/*
|
||
* Interface used by the data access services layer to locate metadata
|
||
* of assemblies in a target.
|
||
*
|
||
* The API client must implement this interface as appropriate for the
|
||
* particular target (for example, a live process or a memory dump).
|
||
*
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(7cef8ba9-2ef7-42bf-973f-4171474f87d9),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugMetaDataLocator : IUnknown
|
||
{
|
||
/*
|
||
* Ask the debugger to return the full path to a module whose metadata is
|
||
* needed to complete an operation the debugger requested.
|
||
*
|
||
* Arguments:
|
||
* wszImagePath - This buffer will always contain a NULL-terminated string
|
||
* representing the full path to the file when available, and the
|
||
* FileName.extension otherwise.
|
||
* dwImageTimeStamp - The TimeStamp from the image's PE headers; can
|
||
* potentially be used for a symsrv lookup.
|
||
* dwImageSize - Size of the image from PE headers; potentially used for
|
||
* a symsrv lookup.
|
||
* cchPathBuffer - The count of WCHARs pointed to by wszPathBuffer.
|
||
* pcchPathBuffer - When the callee returns E_NOT_SUFFICIENT_BUFFER, contains
|
||
* the count of WCHARs needed to store the path.
|
||
* For all other return values, pcchPathBuffer contains the count of
|
||
* WCHARs written to wszPathBuffer.
|
||
* wszPathBuffer - Pointer to a buffer into which the debugger will copy
|
||
* the full path to the file containing the requested metadata.
|
||
* CorOpenFlags.ofReadOnly access to the metadata in this file will
|
||
* be requested.
|
||
*
|
||
* Assumptions:
|
||
* The returned file represents a Windows module containing the metadata
|
||
* needed to complete a request made by the debugger.
|
||
*
|
||
* Return Value:
|
||
* S_OK on success. wszPathBuffer contains the full path to the file and
|
||
* is NULL-terminated.
|
||
*
|
||
* E_NOT_SUFFICIENT_BUFFER if the current size of wszPathBuffer is not
|
||
* sufficient to hold the full path. pcchPathBuffer will contain the
|
||
* needed count of WCHARs, including the terminating NULL.
|
||
* In this case GetMetaData will be called a second time with the
|
||
* requested buffer size.
|
||
*
|
||
* All other failure HRESULTs are interpreted to mean that the file
|
||
* is not retrievable.
|
||
*
|
||
* Notes:
|
||
* If wszImagePath contains a full path for a module from a dump, that
|
||
* path will be the path from the machine where the dump was collected.
|
||
* The file may not exist at this location, or an incorrect file with the
|
||
* same name may be stored on the path.
|
||
*/
|
||
HRESULT GetMetaData( [in] LPCWSTR wszImagePath,
|
||
[in] DWORD dwImageTimeStamp,
|
||
[in] DWORD dwImageSize,
|
||
[in] ULONG32 cchPathBuffer,
|
||
[out, annotation("__out")] ULONG32 * pcchPathBuffer,
|
||
[out, size_is(cchPathBuffer), length_is(*pcchPathBuffer), annotation("__out_ecount_part(cchPathBuffer, *pcchPathBuffer) ")] WCHAR wszPathBuffer[]);
|
||
};
|
||
|
||
|
||
/* ------------------------------------------------------------------------- *
|
||
* User Callback interface
|
||
* ------------------------------------------------------------------------- */
|
||
|
||
|
||
#pragma warning(push)
|
||
#pragma warning(disable:28718) /* disable warning 28718 for interface ICorDebugManagedCallback */
|
||
/*
|
||
* ICorDebugManagedCallback is implemented by the user of the
|
||
* ICorDebug interfaces in order to respond to events in managed code
|
||
* in the debuggee process.
|
||
* This interface handles manage debug events from v1.0/v1.1
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(3d6f5f60-7538-11d3-8d5b-00104b35e7ef),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugManagedCallback : IUnknown
|
||
{
|
||
/*
|
||
* All callbacks are called with the process in the synchronized state
|
||
* All callbacks are serialized, and are called in in the same thread.
|
||
* Each callback implementor must call Continue in a callback to
|
||
* resume execution.
|
||
* If Continue is not called before returning, the process will
|
||
* remain stopped. Continue must later be called before any more
|
||
* event callbacks will happen.
|
||
*
|
||
*/
|
||
|
||
/*
|
||
* Breakpoint is called when a breakpoint is hit.
|
||
*/
|
||
|
||
HRESULT Breakpoint([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugThread *pThread,
|
||
[in] ICorDebugBreakpoint *pBreakpoint);
|
||
|
||
/*
|
||
* StepComplete is called when a step has completed. The stepper
|
||
* may be used to continue stepping if desired (except for TERMINATE
|
||
* reasons.)
|
||
*
|
||
* STEP_NORMAL means that stepping completed normally, in the same
|
||
* function.
|
||
*
|
||
* STEP_RETURN means that stepping continued normally, after the function
|
||
* returned.
|
||
*
|
||
* STEP_CALL means that stepping continued normally, at the start of
|
||
* a newly called function.
|
||
*
|
||
* STEP_EXCEPTION_FILTER means that control passed to an exception filter
|
||
* after an exception was thrown.
|
||
*
|
||
* STEP_EXCEPTION_HANDLER means that control passed to an exception handler
|
||
* after an exception was thrown.
|
||
*
|
||
* STEP_INTERCEPT means that control passed to an interceptor.
|
||
*
|
||
* STEP_EXIT means that the thread exited before the step completed.
|
||
* No more stepping can be performed with the stepper.
|
||
*/
|
||
|
||
typedef enum CorDebugStepReason
|
||
{
|
||
STEP_NORMAL,
|
||
STEP_RETURN,
|
||
STEP_CALL,
|
||
STEP_EXCEPTION_FILTER,
|
||
STEP_EXCEPTION_HANDLER,
|
||
STEP_INTERCEPT,
|
||
STEP_EXIT
|
||
} CorDebugStepReason;
|
||
|
||
HRESULT StepComplete([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugThread *pThread,
|
||
[in] ICorDebugStepper *pStepper,
|
||
[in] CorDebugStepReason reason);
|
||
|
||
/*
|
||
* Break is called when a break opcode in the code stream is
|
||
* executed.
|
||
*/
|
||
|
||
HRESULT Break([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugThread *thread);
|
||
|
||
/*
|
||
* Exception is called when an exception is thrown from managed
|
||
* code, The specific exception can be retrieved from the thread object.
|
||
*
|
||
* If unhandled is FALSE, this is a "first chance" exception that
|
||
* hasn't had a chance to be processed by the application. If
|
||
* unhandled is TRUE, this is an unhandled exception which will
|
||
* terminate the process.
|
||
*/
|
||
|
||
HRESULT Exception([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugThread *pThread,
|
||
[in] BOOL unhandled);
|
||
|
||
/*
|
||
* EvalComplete is called when an evaluation is completed.
|
||
*/
|
||
|
||
HRESULT EvalComplete([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugThread *pThread,
|
||
[in] ICorDebugEval *pEval);
|
||
|
||
/*
|
||
* EvalException is called when an evaluation terminates with
|
||
* an unhandled exception.
|
||
*/
|
||
|
||
HRESULT EvalException([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugThread *pThread,
|
||
[in] ICorDebugEval *pEval);
|
||
|
||
/*
|
||
* CreateProcess is called when a process is first attached to or
|
||
* started.
|
||
*
|
||
* This entry point won't be called until the EE is initialized.
|
||
* Most of the ICorDebug API will return CORDBG_E_NOTREADY prior
|
||
* to the CreateProcess callback.
|
||
*/
|
||
|
||
HRESULT CreateProcess([in] ICorDebugProcess *pProcess);
|
||
|
||
/*
|
||
* ExitProcess is called when a process exits.
|
||
*
|
||
* Note: you don't Continue from an ExitProcess event, and this
|
||
* event may fire asynchronously to other events, while the
|
||
* process appears to be stopped. This can occur if the process
|
||
* dies while stopped, usually due to some external force.
|
||
*
|
||
* If the CLR is already dispatching a managed callback, this event
|
||
* will be delayed until after that callback has returned.
|
||
*
|
||
* This is the only exit/unload event that is guaranteed to get called
|
||
* on shutdown.
|
||
*/
|
||
|
||
HRESULT ExitProcess([in] ICorDebugProcess *pProcess);
|
||
|
||
/*
|
||
* CreateThread is called when a thread first begins executing managed
|
||
* code. The thread will be positioned immediately at the first
|
||
* managed code to be executed.
|
||
*/
|
||
|
||
HRESULT CreateThread([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugThread *thread);
|
||
|
||
/*
|
||
* ExitThread is called when a thread which has run managed code exits.
|
||
* Once this callback is fired, the thread no longer will appear in thread enumerations.
|
||
*/
|
||
|
||
HRESULT ExitThread([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugThread *thread);
|
||
|
||
/*
|
||
* LoadModule is called when a Common Language Runtime module is successfully
|
||
* loaded. This is an appropriate time to examine metadata for the
|
||
* module, set JIT compiler flags, or enable or disable
|
||
* class loading callbacks for the module.
|
||
*/
|
||
|
||
HRESULT LoadModule([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugModule *pModule);
|
||
|
||
/*
|
||
* UnloadModule is called when a Common Language Runtime module (DLL) is unloaded. The module
|
||
* should not be used after this point.
|
||
*/
|
||
|
||
HRESULT UnloadModule([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugModule *pModule);
|
||
|
||
/*
|
||
* LoadClass is called when a class finishes loading. This callback only
|
||
* occurs if ClassLoading has been enabled for the class's module.
|
||
*
|
||
* ClassLoading is always enabled for dynamic modules. This is a good time
|
||
* to update symbols (ICorDebugModule3::CreateReaderForInMemorySymbols) and
|
||
* bind breakpoints to newly generated classes in dynamic modules.
|
||
*/
|
||
|
||
HRESULT LoadClass([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugClass *c);
|
||
|
||
/*
|
||
* UnloadClass is called immediately before a class is unloaded. The class
|
||
* should not be referenced after this point. This callback only occurs if
|
||
* ClassLoading has been enabled for the class's module.
|
||
*/
|
||
|
||
HRESULT UnloadClass([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugClass *c);
|
||
|
||
/*
|
||
* DebuggerError is called when an error occurs while attempting to
|
||
* handle an event from the Common Language Runtime. It is very strongly
|
||
* advised that debuggers log this message to the end user because
|
||
* this callback indicates the debugging services have been disabled due to
|
||
* an error.
|
||
*
|
||
* ICorDebugProcess::GetID() will be safe to call, but all other APIs should
|
||
* not be called and will fail if they are.
|
||
* This includes ICorDebugProcess::Terminate and ICorDebug Process::Detach. The
|
||
* debugger should use OS facilities for terminating processes to shut down the process.
|
||
*/
|
||
HRESULT DebuggerError([in] ICorDebugProcess *pProcess,
|
||
[in] HRESULT errorHR,
|
||
[in] DWORD errorCode);
|
||
|
||
|
||
/*
|
||
* Enum defining log message LoggingLevels
|
||
*/
|
||
typedef enum LoggingLevelEnum
|
||
{
|
||
LTraceLevel0 = 0,
|
||
LTraceLevel1,
|
||
LTraceLevel2,
|
||
LTraceLevel3,
|
||
LTraceLevel4,
|
||
LStatusLevel0 = 20,
|
||
LStatusLevel1,
|
||
LStatusLevel2,
|
||
LStatusLevel3,
|
||
LStatusLevel4,
|
||
LWarningLevel = 40,
|
||
LErrorLevel = 50,
|
||
LPanicLevel = 100
|
||
} LoggingLevelEnum;
|
||
|
||
|
||
typedef enum LogSwitchCallReason
|
||
{
|
||
SWITCH_CREATE,
|
||
SWITCH_MODIFY,
|
||
SWITCH_DELETE
|
||
} LogSwitchCallReason;
|
||
|
||
|
||
/*
|
||
* LogMessage is called when a Common Language Runtime managed thread calls the Log
|
||
* class in the System.Diagnostics package to log an event.
|
||
*/
|
||
HRESULT LogMessage([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugThread *pThread,
|
||
[in] LONG lLevel,
|
||
[in] WCHAR *pLogSwitchName,
|
||
[in] WCHAR *pMessage);
|
||
|
||
/*
|
||
* LogSwitch is called when a Common Language Runtime managed thread calls the LogSwitch
|
||
* class in the System.Diagnostics package to create/modify a LogSwitch.
|
||
*/
|
||
HRESULT LogSwitch([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugThread *pThread,
|
||
[in] LONG lLevel,
|
||
[in] ULONG ulReason,
|
||
[in] WCHAR *pLogSwitchName,
|
||
[in] WCHAR *pParentName);
|
||
|
||
/*
|
||
* CreateAppDomain is called when an app domain is created.
|
||
*/
|
||
HRESULT CreateAppDomain([in] ICorDebugProcess *pProcess,
|
||
[in] ICorDebugAppDomain *pAppDomain);
|
||
|
||
/*
|
||
* ExitAppDomain is called when an app domain exits.
|
||
*/
|
||
HRESULT ExitAppDomain([in] ICorDebugProcess *pProcess,
|
||
[in] ICorDebugAppDomain *pAppDomain);
|
||
|
||
|
||
/*
|
||
* LoadAssembly is called when a Common Language Runtime assembly is successfully
|
||
* loaded.
|
||
*/
|
||
HRESULT LoadAssembly([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugAssembly *pAssembly);
|
||
|
||
/*
|
||
* UnloadAssembly is called when a Common Language Runtime assembly is unloaded. The assembly
|
||
* should not be used after this point.
|
||
*/
|
||
HRESULT UnloadAssembly([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugAssembly *pAssembly);
|
||
|
||
/*
|
||
* ControlCTrap is called if a CTRL-C is trapped in the process being
|
||
* debugged. All appdomains within the process are stopped for
|
||
* this callback.
|
||
* Return values:
|
||
* S_OK : Debugger will handle the ControlC Trap
|
||
* S_FALSE : Debugger won't handle the ControlC Trap
|
||
*/
|
||
HRESULT ControlCTrap([in] ICorDebugProcess *pProcess);
|
||
|
||
/*
|
||
* NameChange() is called if either an AppDomain's or
|
||
* Thread's name changes.
|
||
*/
|
||
HRESULT NameChange([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugThread *pThread);
|
||
|
||
/*
|
||
* UpdateModuleSymbols is called when PDB debug symbols are available for an
|
||
* in-memory module. This is a debugger's chance to load the symbols
|
||
* (using ISymUnmanagedBinder::GetReaderForStream), and bind source-level
|
||
* breakpoints for the module.
|
||
*
|
||
* This callback is no longer dispatched for dynamic modules. Instead,
|
||
* debuggers should call ICorDebugModule3::CreateReaderForInMemorySymbols
|
||
* to obtain a symbol reader for a dynamic module.
|
||
*/
|
||
HRESULT UpdateModuleSymbols([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugModule *pModule,
|
||
[in] IStream *pSymbolStream);
|
||
|
||
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
HRESULT EditAndContinueRemap([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugThread *pThread,
|
||
[in] ICorDebugFunction *pFunction,
|
||
[in] BOOL fAccurate);
|
||
|
||
/*
|
||
* BreakpointSetError is called if the CLR was unable to accuratley bind a breakpoint that
|
||
* was set before a function was JIT compiled. The given breakpoint will never be hit. The
|
||
* debugger should deactivate it and rebind it appropiatley.
|
||
*/
|
||
HRESULT BreakpointSetError([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugThread *pThread,
|
||
[in] ICorDebugBreakpoint *pBreakpoint,
|
||
[in] DWORD dwError);
|
||
};
|
||
#pragma warning(pop)
|
||
|
||
#pragma warning(push)
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(264EA0FC-2591-49AA-868E-835E6515323F),
|
||
pointer_default(unique)
|
||
]
|
||
|
||
interface ICorDebugManagedCallback3 : IUnknown
|
||
{
|
||
/* Callback indicating an enabled custom debugger notification has been
|
||
* raised. pThread points to the thread that issued the notification.
|
||
* A subsequent call to GetCurrentCustomDebuggerNotification will retrieve the object that was passed to
|
||
* System.Diagnostics.Debugger.CustomNotification, whose type will be one
|
||
* that has been enabled via SetEnableCustomNotification.
|
||
* Note that this will return non-null if and only if we are currently inside a CustomNotification
|
||
* callback.
|
||
* The debugger can read type-specific parameters from fields of the data
|
||
* object, and store responses into fields.
|
||
* ICorDebug imposes no policy on the types of notifications or their
|
||
* contents, and their semantics are strictly a contract between
|
||
* debuggers and applications/frameworks.
|
||
*/
|
||
HRESULT CustomNotification([in] ICorDebugThread * pThread, [in] ICorDebugAppDomain * pAppDomain);
|
||
}
|
||
|
||
|
||
#pragma warning(disable:28718) /* disable warning 28718 for interface ICorDebugManagedCallback2 */
|
||
|
||
/*
|
||
* ICorDebugManagedCallback2 is a logical extension to ICorDebugManagedCallback.
|
||
* This handles new debug events introduced in V2.0. A debugger's callback object
|
||
* to ICorDebug::SetManagedHandler must implement this interface if it is debugging v2.0 apps.
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(250E5EEA-DB5C-4C76-B6F3-8C46F12E3203),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugManagedCallback2 : IUnknown
|
||
{
|
||
|
||
/*
|
||
* FunctionRemapOpportunity is fired whenever execution reaches a sequence point in an older version
|
||
* of an edited function. This event gives the debugger an opportunity to remap the IP to its proper
|
||
* place in the new version by calling ICorDebugILFrame2::RemapFunction. If the debugger does not call
|
||
* RemapFunction before calling Continue, the runtime will continue executing the old code and will
|
||
* fire another FunctionRemapOpportunity callback at the next sequence point
|
||
*/
|
||
HRESULT FunctionRemapOpportunity([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugThread *pThread,
|
||
[in] ICorDebugFunction *pOldFunction,
|
||
[in] ICorDebugFunction *pNewFunction,
|
||
[in] ULONG32 oldILOffset);
|
||
|
||
/*
|
||
* CreateConnection is called when a new connection is created.
|
||
*/
|
||
HRESULT CreateConnection([in] ICorDebugProcess *pProcess,
|
||
[in] CONNID dwConnectionId,
|
||
[in] WCHAR *pConnName);
|
||
|
||
/*
|
||
* ChangeConnection is called when a connection's set of tasks changes.
|
||
*/
|
||
HRESULT ChangeConnection([in] ICorDebugProcess *pProcess,
|
||
[in] CONNID dwConnectionId );
|
||
|
||
/*
|
||
* DestroyConnection is called when a connection is ended.
|
||
*/
|
||
HRESULT DestroyConnection([in] ICorDebugProcess *pProcess,
|
||
[in] CONNID dwConnectionId );
|
||
|
||
|
||
|
||
|
||
|
||
|
||
typedef enum CorDebugExceptionCallbackType
|
||
{
|
||
DEBUG_EXCEPTION_FIRST_CHANCE = 1, /* Fired when exception thrown */
|
||
DEBUG_EXCEPTION_USER_FIRST_CHANCE = 2, /* Fired when search reaches first user code */
|
||
DEBUG_EXCEPTION_CATCH_HANDLER_FOUND = 3, /* Fired if & when search finds a handler */
|
||
DEBUG_EXCEPTION_UNHANDLED = 4 /* Fired if search doesnt find a handler */
|
||
} CorDebugExceptionCallbackType;
|
||
|
||
|
||
typedef enum CorDebugExceptionFlags
|
||
{
|
||
DEBUG_EXCEPTION_CAN_BE_INTERCEPTED = 0x0001 /* Indicates interceptable exception */
|
||
} CorDebugExceptionFlags;
|
||
|
||
|
||
/*
|
||
* Exception is called at various points during the search phase of the
|
||
* exception-handling process. The exception being processed can be
|
||
* retrieved from the ICorDebugThread.
|
||
*/
|
||
HRESULT Exception( [in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugThread *pThread,
|
||
[in] ICorDebugFrame *pFrame,
|
||
[in] ULONG32 nOffset,
|
||
[in] CorDebugExceptionCallbackType dwEventType,
|
||
[in] DWORD dwFlags );
|
||
|
||
|
||
typedef enum CorDebugExceptionUnwindCallbackType
|
||
{
|
||
DEBUG_EXCEPTION_UNWIND_BEGIN = 1, /* Fired at the beginning of the unwind */
|
||
DEBUG_EXCEPTION_INTERCEPTED = 2 /* Fired after an exception has been intercepted */
|
||
} CorDebugExceptionUnwindCallbackType;
|
||
|
||
|
||
|
||
/*
|
||
* For non-intercepted exceptions, ExceptionUnwind is called at the beginning of the second pass
|
||
* when we start to unwind the stack. For intercepted exceptions, ExceptionUnwind is called when
|
||
* the interception is complete, conceptually at the end of the second pass.
|
||
*
|
||
* dwFlags is not currently used.
|
||
*/
|
||
HRESULT ExceptionUnwind( [in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugThread *pThread,
|
||
[in] CorDebugExceptionUnwindCallbackType dwEventType,
|
||
[in] DWORD dwFlags );
|
||
|
||
/*
|
||
* FunctionRemapComplete is fired whenever execution has completed switching over to a
|
||
* new version of an edited function (as requested by a call to ICorDebugILFrame2::RemapFunction).
|
||
* At this point (and no sooner) steppers can be added to that new version of the function.
|
||
*/
|
||
HRESULT FunctionRemapComplete([in] ICorDebugAppDomain *pAppDomain,
|
||
[in] ICorDebugThread *pThread,
|
||
[in] ICorDebugFunction *pFunction);
|
||
|
||
// Notification that an Managed Debug Assistant (MDA) was hit in the debuggee process.
|
||
// - MDAs are heuristic warnings and do not require any explicit debugger action (other than continue, of course) for proper functionality.
|
||
// - The CLR can change what MDAs are fired (and what data is in any given MDA) at any point.
|
||
// - Therefore, debuggers should not build any specific functionality requiring specific MDAs patterns.
|
||
// - MDAs may be queued and fired "after the fact". This could happen if the runtime needs to slip from when an
|
||
// MDA occurs to get to a safe point for firing it. It also means the runtime reserves the right to fire a bunch of MDAs
|
||
// in a single set of callback queue (similar for what we do w/ attach events).
|
||
//
|
||
// See the MDA documentation for how to enable / disable notifications.
|
||
//
|
||
// Parameters:
|
||
// - pController is the controller object (process or appdomain) that the MDA occurred in.
|
||
// Clients should not make any assumption about whether the controller is a process or appdomain (though they can
|
||
// always QI to find out).
|
||
// Call continue on this to resume the debuggee.
|
||
// - pThread - managed thread on which the debug event occured. If the MDA occurred on an unmanaged thread then
|
||
// this will be null. Get the OS thread ID from the MDA object itself.
|
||
// - pMDA is an object containing MDA information.
|
||
// Suggested usage is that the client does not keep a reference to the MDA object after returning from this callback
|
||
// because that lets the CLR quickly recycle the MDA's memory. This could be a performance win if there are
|
||
// lots of MDAs firing.
|
||
HRESULT MDANotification(
|
||
[in] ICorDebugController * pController,
|
||
[in] ICorDebugThread *pThread,
|
||
[in] ICorDebugMDA * pMDA
|
||
);
|
||
|
||
};
|
||
#pragma warning(pop)
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(5263E909-8CB5-11d3-BD2F-0000F80849BD),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugUnmanagedCallback : IUnknown
|
||
{
|
||
/*
|
||
* DebugEvent is called when a DEBUG_EVENT is received which is
|
||
* not directly related to the Common Language Runtime.
|
||
*
|
||
* DO NOT USE any parts of the debugging API from the Win32 Event
|
||
* Thread. Only ICorDebugController::Continue() can be called on
|
||
* the Win32 Event Thread, and only when continuing from an out-of-band
|
||
* event.
|
||
*
|
||
* This callback is an exception to the rules about callbacks.
|
||
* When this callback is called, the process will be in the "raw"
|
||
* OS debug stopped state. The process will not be synchronized.
|
||
* The process will automatically enter the synchronized state when
|
||
* necessary to satisfy certain requests for information about
|
||
* managed code. (Note that this may result in other nested
|
||
* DebugEvent callbacks.)
|
||
*
|
||
* Call ClearCurrentException on the process to ignore an
|
||
* exception event before continuing the process. (Causes
|
||
* DBG_CONTINUE to be sent on continue rather than
|
||
* DBG_EXCEPTION_NOT_HANDLED)
|
||
* Out-of-band Breakpoint and single-step exceptions are automatically cleared.
|
||
*
|
||
* fOutOfBand will be FALSE if the debugging services support
|
||
* interaction with the process's managed state while the process
|
||
* is stopped due to this event. fOutOfBand will be TRUE if
|
||
* interaction with the process's managed state is impossible until
|
||
* the unmanaged event is continued from.
|
||
*
|
||
* Out-Of-Band events can come at anytime; even when there debuggee appears stopped
|
||
* and even when there's already an outstanding inband event.
|
||
*
|
||
* In v2.0, it is strongly recommended that the debugger just immediately
|
||
* continues OOB breakpoint events. The debugger should be using the ICorDebugProcess2
|
||
* SetUnmanagedBreakpoint and ClearUnmanagedBreakpoint APIs to add/remove breakpoints.
|
||
* Those APIs will already skip over any OOB breakpoints automatically. Thus the only
|
||
* oob breakpoints that get dispatched should be raw breakpoints already in the
|
||
* instruction stream (eg, like a call to kernel32!DebugBreak). In these cases,
|
||
* just continuing past the breakpoint is the correct thing to do. Do not try to use
|
||
* any other portion of the API like ClearCurrentException or Get/SetThreadContext.
|
||
*
|
||
*/
|
||
|
||
HRESULT DebugEvent([in] LPDEBUG_EVENT pDebugEvent,
|
||
[in] BOOL fOutOfBand);
|
||
};
|
||
|
||
/* ------------------------------------------------------------------------- *
|
||
* Debugger interface
|
||
* ------------------------------------------------------------------------- */
|
||
|
||
|
||
typedef enum CorDebugCreateProcessFlags
|
||
{
|
||
DEBUG_NO_SPECIAL_OPTIONS = 0x0000
|
||
} CorDebugCreateProcessFlags;
|
||
|
||
|
||
/* ICorDebugHeapValue::CreateHandle takes a handle flavor.
|
||
* A strong handle will keep an object alive while a weak track resurrection
|
||
* will not.
|
||
*/
|
||
typedef enum CorDebugHandleType
|
||
{
|
||
HANDLE_STRONG = 1,
|
||
HANDLE_WEAK_TRACK_RESURRECTION = 2
|
||
} CorDebugHandleType;
|
||
|
||
#pragma warning(push)
|
||
#pragma warning(disable:28718) /* disable warning 28718 for interface ICorDebug */
|
||
/*
|
||
* ICorDebug represents an event processing loop for a debugger process.
|
||
*
|
||
* The debugger must wait for the ExitProcess callback from all
|
||
* processes being debugged before releasing this interface.
|
||
*
|
||
* The ICorDebug object is the initial object to control all further managed debugging.
|
||
* In v1.0 + v1.1, this object was a CoClass created from COM.
|
||
* In v2.0, this object is no longer a CoClass and must be created from the function:
|
||
* CreateDebuggingInterfaceFromVersion(
|
||
* int iDebuggerVersion, // <--- CorDebugVersion_2_0 if Debugger is V2.0
|
||
* LPCWSTR szDebuggeeVersion, // <--- version string of debuggee. Eg, "v1.1.4322"
|
||
* IUnknown ** ppCordb
|
||
* )
|
||
* declared in mscoree.idl.
|
||
* This new creation function is more version-aware. It allows clients to get a
|
||
* specific implementation (as specified by szDebuggeeVersion) of ICorDebug, which
|
||
* also emulates a specific version of the debugging API (as specified by iDebuggerVersion).
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(3d6f5f61-7538-11d3-8d5b-00104b35e7ef),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebug : IUnknown
|
||
{
|
||
/*
|
||
* The debugger calls this method at creation time to initialize the debugging
|
||
* services, and must be called at creation time before any other method on
|
||
* ICorDebug is called.
|
||
*/
|
||
|
||
HRESULT Initialize();
|
||
|
||
/*
|
||
* Terminate must be called when the ICorDebug is no longer needed.
|
||
*
|
||
* NOTE: Terminate should not be called until an ExitProcess callback has
|
||
* been received for all processes being debugged.
|
||
*
|
||
*/
|
||
|
||
HRESULT Terminate();
|
||
|
||
/*
|
||
* SetManagedHandler should be called at creation time to specify the
|
||
* event handler object for managed events.
|
||
*
|
||
* Returns:
|
||
* S_OK on success.
|
||
* E_NOINTERFACE - if pCallback does not implement sufficient interfaces
|
||
* to receive debug events for the version of the API it requested.
|
||
* Eg, if debugging a V2.0 app, pCallback must implement ICorDebugManagedCallback2.
|
||
*
|
||
*/
|
||
|
||
HRESULT SetManagedHandler([in] ICorDebugManagedCallback *pCallback);
|
||
|
||
/*
|
||
* SetUnmanagedHandler should be called at creation time to specify the
|
||
* event handler object for unmanaged events.
|
||
*
|
||
* This should be set after Initialize and before any calls to CreateProcess or DebugActiveProcess.
|
||
*
|
||
* However, for legacy purposes, it is not absolutely required to set this until
|
||
* before the first native debug event is fired. Specifically, if CreateProcess has the
|
||
* CREATE_SUSPENDED flag, native debug events will not be dispatched until the main thread
|
||
* is resumed.
|
||
* DebugActiveProcess will dispatch native debug events immediately, and so the unmanaged callback
|
||
* must be set before DebugActiveProcess is called.
|
||
*
|
||
* Returns:
|
||
* S_OK if callback pointer is successfully updated.
|
||
* failure on any failure.
|
||
*
|
||
*/
|
||
|
||
HRESULT SetUnmanagedHandler([in] ICorDebugUnmanagedCallback *pCallback);
|
||
|
||
/*
|
||
* CreateProcess launches a process under the control of the debugger
|
||
* All parameters are the same as the win32 CreateProcess call.
|
||
*
|
||
* To enable unmanaged (mixed-mode) debugging, pass
|
||
* DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS to dwCreationFlags. DEBUG_PROCESS
|
||
* alone is not supported. If only managed debugging is desired, do not set
|
||
* these flags.
|
||
*
|
||
* The debugger and debuggee share a single console, then it's possible for
|
||
* the debuggee to hold "console locks" and then get stopped at a debug event.
|
||
* The debugger will then block trying to use the console. This is only an issue
|
||
* when interop debugging and if debugger + debuggee share the console.
|
||
* It is recommended to use the CREATE_NEW_CONSOLE flag to avoid this problem.
|
||
*
|
||
*/
|
||
|
||
HRESULT CreateProcess([in] LPCWSTR lpApplicationName,
|
||
[in] LPWSTR lpCommandLine,
|
||
[in] LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||
[in] LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||
[in] BOOL bInheritHandles,
|
||
[in] DWORD dwCreationFlags,
|
||
[in] PVOID lpEnvironment,
|
||
[in] LPCWSTR lpCurrentDirectory,
|
||
[in] LPSTARTUPINFOW lpStartupInfo,
|
||
[in] LPPROCESS_INFORMATION lpProcessInformation,
|
||
[in] CorDebugCreateProcessFlags debuggingFlags,
|
||
[out] ICorDebugProcess **ppProcess);
|
||
|
||
/*
|
||
* DebugActiveProcess is used to attach to an existing process.
|
||
*
|
||
* If win32Attach is TRUE, then the debugger becomes the Win32
|
||
* debugger for the process and will begin dispatching the
|
||
* unmanaged callbacks.
|
||
*
|
||
*/
|
||
|
||
HRESULT DebugActiveProcess([in] DWORD id,
|
||
[in] BOOL win32Attach,
|
||
[out] ICorDebugProcess **ppProcess);
|
||
|
||
/*
|
||
* EnumerateProcesses returns an enum of processes being debugged.
|
||
*
|
||
*/
|
||
|
||
HRESULT EnumerateProcesses([out] ICorDebugProcessEnum **ppProcess);
|
||
|
||
/*
|
||
* GetProcess returns the ICorDebugProcess with the given OS Id.
|
||
*/
|
||
|
||
HRESULT GetProcess([in] DWORD dwProcessId,
|
||
[out] ICorDebugProcess **ppProcess);
|
||
|
||
/*
|
||
* CanLaunchOrAttach returns S_OK if the debugging services believe that
|
||
* launching a new process or attaching to the given process is possible
|
||
* given what it knows about the current machine and runtime configuration.
|
||
*
|
||
* If you plan to launch with win32 debugging enabled, or to attach with
|
||
* win32 debugging enabled then pass in TRUE for win32DebuggineEnabled.
|
||
* The answer may be different if this option will be used.
|
||
*
|
||
* Note: the rest of the API will not stop you from launching or attaching
|
||
* to a process anyway. This function is purely informational.
|
||
*
|
||
* Possible HRESULTs: S_OK, CORDBG_E_DEBUGGING_NOT_POSSIBLE,
|
||
* CORDBG_E_KERNEL_DEBUGGER_PRESENT, CORDBG_E_KERNEL_DEBUGGER_ENABLED
|
||
*
|
||
*/
|
||
|
||
HRESULT CanLaunchOrAttach([in] DWORD dwProcessId,
|
||
[in] BOOL win32DebuggingEnabled);
|
||
};
|
||
#pragma warning(pop)
|
||
|
||
/*
|
||
* A debugger can implement this interface and pass it to ICorDebugRemote to specify the host name of the
|
||
* target machine in Mac remote debugging scenarios. This is only supported on Silverlight.
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(C3ED8383-5A49-4cf5-B4B7-01864D9E582D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugRemoteTarget : IUnknown
|
||
{
|
||
/*
|
||
* Return the host name of the target machine. The host name can either be a fully qualified domain name or
|
||
* an IPv4 address. If cchHostName is 0 and szHostName is NULL, this function just returns the number of
|
||
* characters including the NULL character in the host name.
|
||
*
|
||
* cchHostName is the number of characters in the buffer szHostName. If this is 0, then szHostName must
|
||
* be NULL. If it is not 0, then szHostName must be non-NULL.
|
||
*
|
||
* pcchHostName returns the number of characters including the NULL character in the host name. This can
|
||
* be NULL.
|
||
*
|
||
* szHostName is the buffer for returning the host name.
|
||
*/
|
||
|
||
HRESULT GetHostName([in] ULONG32 cchHostName,
|
||
[out, annotation("__out")] ULONG32 * pcchHostName,
|
||
[out, size_is(cchHostName), length_is(*pcchHostName), annotation("__out_ecount_part_opt(cchHostName, *pcchHostName)")]
|
||
WCHAR szHostName[]);
|
||
}
|
||
|
||
/*
|
||
* A debugger can QI for this interface from an ICorDebug interface in order to specify a target machine in
|
||
* Mac remote debugging scenarios. This is only supported on Silverlight.
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(D5EBB8E2-7BBE-4c1d-98A6-A3C04CBDEF64),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugRemote : IUnknown
|
||
{
|
||
HRESULT CreateProcessEx([in] ICorDebugRemoteTarget * pRemoteTarget,
|
||
[in] LPCWSTR lpApplicationName,
|
||
[in, annotation("__in")] LPWSTR lpCommandLine,
|
||
[in] LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||
[in] LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||
[in] BOOL bInheritHandles,
|
||
[in] DWORD dwCreationFlags,
|
||
[in] PVOID lpEnvironment,
|
||
[in] LPCWSTR lpCurrentDirectory,
|
||
[in] LPSTARTUPINFOW lpStartupInfo,
|
||
[in] LPPROCESS_INFORMATION lpProcessInformation,
|
||
[in] CorDebugCreateProcessFlags debuggingFlags,
|
||
[out] ICorDebugProcess ** ppProcess);
|
||
|
||
|
||
HRESULT DebugActiveProcessEx([in] ICorDebugRemoteTarget * pRemoteTarget,
|
||
[in] DWORD dwProcessId,
|
||
[in] BOOL fWin32Attach,
|
||
[out] ICorDebugProcess ** ppProcess);
|
||
}
|
||
|
||
typedef struct _COR_VERSION
|
||
{
|
||
DWORD dwMajor;
|
||
DWORD dwMinor;
|
||
DWORD dwBuild;
|
||
DWORD dwSubBuild;
|
||
} COR_VERSION;
|
||
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(ECCCCF2E-B286-4b3e-A983-860A8793D105),
|
||
pointer_default(unique)
|
||
]
|
||
/*
|
||
* Sets the maximum version of the runtime supported by the debugger using this
|
||
* object.
|
||
*/
|
||
interface ICorDebug2 : IUnknown
|
||
{
|
||
typedef enum CorDebugInterfaceVersion
|
||
{
|
||
CorDebugInvalidVersion = 0,
|
||
CorDebugVersion_1_0 = CorDebugInvalidVersion + 1,
|
||
ver_ICorDebugManagedCallback = CorDebugVersion_1_0,
|
||
ver_ICorDebugUnmanagedCallback = CorDebugVersion_1_0,
|
||
ver_ICorDebug = CorDebugVersion_1_0,
|
||
ver_ICorDebugController = CorDebugVersion_1_0,
|
||
ver_ICorDebugAppDomain = CorDebugVersion_1_0,
|
||
ver_ICorDebugAssembly = CorDebugVersion_1_0,
|
||
ver_ICorDebugProcess = CorDebugVersion_1_0,
|
||
ver_ICorDebugBreakpoint = CorDebugVersion_1_0,
|
||
ver_ICorDebugFunctionBreakpoint = CorDebugVersion_1_0,
|
||
ver_ICorDebugModuleBreakpoint = CorDebugVersion_1_0,
|
||
ver_ICorDebugValueBreakpoint = CorDebugVersion_1_0,
|
||
ver_ICorDebugStepper = CorDebugVersion_1_0,
|
||
ver_ICorDebugRegisterSet = CorDebugVersion_1_0,
|
||
ver_ICorDebugThread = CorDebugVersion_1_0,
|
||
ver_ICorDebugChain = CorDebugVersion_1_0,
|
||
ver_ICorDebugFrame = CorDebugVersion_1_0,
|
||
ver_ICorDebugILFrame = CorDebugVersion_1_0,
|
||
ver_ICorDebugNativeFrame = CorDebugVersion_1_0,
|
||
ver_ICorDebugModule = CorDebugVersion_1_0,
|
||
ver_ICorDebugFunction = CorDebugVersion_1_0,
|
||
ver_ICorDebugCode = CorDebugVersion_1_0,
|
||
ver_ICorDebugClass = CorDebugVersion_1_0,
|
||
ver_ICorDebugEval = CorDebugVersion_1_0,
|
||
ver_ICorDebugValue = CorDebugVersion_1_0,
|
||
ver_ICorDebugGenericValue = CorDebugVersion_1_0,
|
||
ver_ICorDebugReferenceValue = CorDebugVersion_1_0,
|
||
ver_ICorDebugHeapValue = CorDebugVersion_1_0,
|
||
ver_ICorDebugObjectValue = CorDebugVersion_1_0,
|
||
ver_ICorDebugBoxValue = CorDebugVersion_1_0,
|
||
ver_ICorDebugStringValue = CorDebugVersion_1_0,
|
||
ver_ICorDebugArrayValue = CorDebugVersion_1_0,
|
||
ver_ICorDebugContext = CorDebugVersion_1_0,
|
||
ver_ICorDebugEnum = CorDebugVersion_1_0,
|
||
ver_ICorDebugObjectEnum = CorDebugVersion_1_0,
|
||
ver_ICorDebugBreakpointEnum = CorDebugVersion_1_0,
|
||
ver_ICorDebugStepperEnum = CorDebugVersion_1_0,
|
||
ver_ICorDebugProcessEnum = CorDebugVersion_1_0,
|
||
ver_ICorDebugThreadEnum = CorDebugVersion_1_0,
|
||
ver_ICorDebugFrameEnum = CorDebugVersion_1_0,
|
||
ver_ICorDebugChainEnum = CorDebugVersion_1_0,
|
||
ver_ICorDebugModuleEnum = CorDebugVersion_1_0,
|
||
ver_ICorDebugValueEnum = CorDebugVersion_1_0,
|
||
ver_ICorDebugCodeEnum = CorDebugVersion_1_0,
|
||
ver_ICorDebugTypeEnum = CorDebugVersion_1_0,
|
||
ver_ICorDebugErrorInfoEnum = CorDebugVersion_1_0,
|
||
ver_ICorDebugAppDomainEnum = CorDebugVersion_1_0,
|
||
ver_ICorDebugAssemblyEnum = CorDebugVersion_1_0,
|
||
ver_ICorDebugEditAndContinueErrorInfo = CorDebugVersion_1_0,
|
||
ver_ICorDebugEditAndContinueSnapshot = CorDebugVersion_1_0,
|
||
|
||
CorDebugVersion_1_1 = CorDebugVersion_1_0 + 1,
|
||
// no interface definitions in v1.1
|
||
|
||
CorDebugVersion_2_0 = CorDebugVersion_1_1 + 1,
|
||
|
||
ver_ICorDebugManagedCallback2 = CorDebugVersion_2_0,
|
||
ver_ICorDebugAppDomain2 = CorDebugVersion_2_0,
|
||
ver_ICorDebugAssembly2 = CorDebugVersion_2_0,
|
||
ver_ICorDebugProcess2 = CorDebugVersion_2_0,
|
||
ver_ICorDebugStepper2 = CorDebugVersion_2_0,
|
||
ver_ICorDebugRegisterSet2 = CorDebugVersion_2_0,
|
||
ver_ICorDebugThread2 = CorDebugVersion_2_0,
|
||
ver_ICorDebugILFrame2 = CorDebugVersion_2_0,
|
||
ver_ICorDebugInternalFrame = CorDebugVersion_2_0,
|
||
ver_ICorDebugModule2 = CorDebugVersion_2_0,
|
||
ver_ICorDebugFunction2 = CorDebugVersion_2_0,
|
||
ver_ICorDebugCode2 = CorDebugVersion_2_0,
|
||
ver_ICorDebugClass2 = CorDebugVersion_2_0,
|
||
ver_ICorDebugValue2 = CorDebugVersion_2_0,
|
||
ver_ICorDebugEval2 = CorDebugVersion_2_0,
|
||
ver_ICorDebugObjectValue2 = CorDebugVersion_2_0,
|
||
|
||
// CLR v4 - next major CLR version after CLR v2
|
||
// Includes Silverlight 4
|
||
CorDebugVersion_4_0 = CorDebugVersion_2_0 + 1,
|
||
|
||
ver_ICorDebugThread3 = CorDebugVersion_4_0,
|
||
ver_ICorDebugThread4 = CorDebugVersion_4_0,
|
||
ver_ICorDebugStackWalk = CorDebugVersion_4_0,
|
||
ver_ICorDebugNativeFrame2 = CorDebugVersion_4_0,
|
||
ver_ICorDebugInternalFrame2 = CorDebugVersion_4_0,
|
||
ver_ICorDebugRuntimeUnwindableFrame = CorDebugVersion_4_0,
|
||
ver_ICorDebugHeapValue3 = CorDebugVersion_4_0,
|
||
ver_ICorDebugBlockingObjectEnum = CorDebugVersion_4_0,
|
||
|
||
CorDebugLatestVersion = CorDebugVersion_4_0
|
||
|
||
} CorDebugInterfaceVersion;
|
||
|
||
};
|
||
|
||
/* ------------------------------------------------------------------------- *
|
||
* Controller interface
|
||
* ------------------------------------------------------------------------- */
|
||
|
||
|
||
/*
|
||
* A thread's DebugState determines whether the debugger lets a thread
|
||
* run or not. Possible states are:
|
||
*
|
||
* THREAD_RUN - thread runs freely, unless a debug event occurs
|
||
* THREAD_SUSPEND - thread cannot run.
|
||
*
|
||
* NOTE: We allow for message pumping via a callback provided to the Hosting
|
||
* API, thus we don't need an 'interrupted' state here.
|
||
*/
|
||
|
||
typedef enum CorDebugThreadState
|
||
{
|
||
THREAD_RUN,
|
||
THREAD_SUSPEND
|
||
} CorDebugThreadState;
|
||
|
||
|
||
/*
|
||
* ICorDebugController represents a scope at which program execution context
|
||
* can be controlled. It represents either a process or an app domain.
|
||
*
|
||
* If this is the controller of a process, this controller affects all
|
||
* threads in the process. Otherwise it just affects the threads of
|
||
* a particular app domain
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(3d6f5f62-7538-11d3-8d5b-00104b35e7ef),
|
||
pointer_default(unique)
|
||
]
|
||
|
||
interface ICorDebugController : IUnknown
|
||
{
|
||
/*
|
||
* Stop performs a cooperative stop on all threads running managed
|
||
* code in the process. When managed-only debugging, unmanaged threads may continue
|
||
* to run (but will be blocked when trying to call managed code). When-interop debugging,
|
||
* unmanaged threads will also be stopped.
|
||
* The timeout value is currently ignored and treated as INFINTE (-1).
|
||
* If the cooperative stop fails due to a deadlock, all threads are suspended (and E_TIMEOUT is returned)
|
||
*
|
||
* NOTE: This function is the one function in the debugging API
|
||
* that is synchronous. When Stop returns with S_OK, the process
|
||
* is stopped. (No callback will be given to notify of the stop.)
|
||
* The debugger must call Continue when it wishes to allow
|
||
* the process to resume running.
|
||
*
|
||
* The debugger maintains a "stop-counter". When the counter goes to zero, the
|
||
* Controller is resumed. Each call to Stop() or each dispatched callback will increment
|
||
* the counter. Each call to continue will decrement the counter.
|
||
*/
|
||
|
||
HRESULT Stop([in] DWORD dwTimeoutIgnored);
|
||
|
||
/*
|
||
* Continue continues the process after a call to Stop.
|
||
*
|
||
* Continue continues the process. fIsOutOfBand is set to TRUE
|
||
* if continuing from an unmanaged event that was sent with the
|
||
* fOutOfBand flag in the unmanaged callback and it is set to
|
||
* FALSE if continuing from a managed event or a normal
|
||
* unmanaged event.
|
||
*
|
||
* When doing mixed-mode debugging, Continue cannot be called on
|
||
* the Win32 Event Thread unless it is continuing from an
|
||
* out-of-band event.
|
||
*/
|
||
|
||
HRESULT Continue([in] BOOL fIsOutOfBand);
|
||
|
||
/*
|
||
* IsRunning returns TRUE if the threads in the process are running freely.
|
||
*
|
||
*/
|
||
|
||
HRESULT IsRunning([out] BOOL *pbRunning);
|
||
|
||
/*
|
||
* HasQueuedCallbacks returns TRUE if there are currently managed
|
||
* callbacks which are queued up for the given thread. These
|
||
* callbacks will be dispatched one at a time, each time Continue
|
||
* is called.
|
||
*
|
||
* The debugger can check this flag if it wishes to report multiple
|
||
* debugging events which occur simultaneously.
|
||
*
|
||
* If NULL is given for the pThread parameter, HasQueuedCallbacks
|
||
* will return TRUE if there are currently managed callbacks
|
||
* queued for any thread.
|
||
*
|
||
* Note that once debug events have been queued, they've already occured,
|
||
* and so the debugger must drain the entire queue to be sure of the state
|
||
* of the debuggee. For example, if the queue contains 2 debug events on thread X,
|
||
* and the debugger suspends thread X after the 1st debug event and then calls continue,
|
||
* the 2nd debug event for thread X will still be dispatched even though the thread
|
||
* is suspended.
|
||
*
|
||
*/
|
||
|
||
HRESULT HasQueuedCallbacks([in] ICorDebugThread *pThread,
|
||
[out] BOOL *pbQueued);
|
||
|
||
/*
|
||
* EnumerateThreads returns an enum of all managed threads active in the process.
|
||
* A thread is considered Managed threads after the CreateThread callback has been
|
||
* dispatched and before the ExitThread callback has been dispatched.
|
||
* A managed thread may not necessarily have any managed frames on its stack.
|
||
*
|
||
* Threads can be enumerated even before the CreateProcess callback. The enumeration
|
||
* will naturally be empty.
|
||
*/
|
||
|
||
HRESULT EnumerateThreads([out] ICorDebugThreadEnum **ppThreads);
|
||
|
||
/*
|
||
* SetAllThreadsDebugState sets the current debug state of each thread.
|
||
* See ICorDebugThread::SetDebugState for details.
|
||
*
|
||
* The pExceptThisThread parameter allows you to specify one
|
||
* thread which is exempted from the debug state change. Pass NULL
|
||
* if you want to affect all threads.
|
||
*
|
||
* This may affect threads not visible via EnumerateThreads, so threads suspended
|
||
* via this API will need to be resumed via this API too.
|
||
*
|
||
*/
|
||
|
||
HRESULT SetAllThreadsDebugState([in] CorDebugThreadState state,
|
||
[in] ICorDebugThread *pExceptThisThread);
|
||
|
||
/*
|
||
* Detach detaches the debugger from the process. The process
|
||
* continues execution normally. The ICorDebugProcess object is
|
||
* no longer valid and no further callbacks will occur. This is
|
||
* not implemented for AppDomains (detaching is process-wide).
|
||
*
|
||
* Note that currently if unmanaged debugging is enabled this call will
|
||
* fail due to OS limitations.
|
||
*
|
||
* Returns S_OK on success.
|
||
*
|
||
*/
|
||
|
||
HRESULT Detach();
|
||
|
||
/*
|
||
* Terminate terminates the process (with extreme prejudice, I might add).
|
||
*
|
||
* NOTE: If the process or appdomain is stopped when Terminate is called,
|
||
* the process or appdomain should be continued using Continue so that the
|
||
* ExitProcess or ExitAppDomain callback is received.
|
||
*
|
||
* NOTE: This method is not implemented by an appdomain.
|
||
*/
|
||
|
||
HRESULT Terminate([in] UINT exitCode);
|
||
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
|
||
HRESULT CanCommitChanges([in] ULONG cSnapshots,
|
||
[in, size_is(cSnapshots)] ICorDebugEditAndContinueSnapshot *pSnapshots[],
|
||
[out] ICorDebugErrorInfoEnum **pError);
|
||
|
||
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
|
||
HRESULT CommitChanges([in] ULONG cSnapshots,
|
||
[in, size_is(cSnapshots)] ICorDebugEditAndContinueSnapshot *pSnapshots[],
|
||
[out] ICorDebugErrorInfoEnum **pError);
|
||
|
||
};
|
||
|
||
|
||
|
||
#pragma warning(push)
|
||
#pragma warning(disable:28718) /* disable warning 28718 for interface ICorDebugAppDomain */
|
||
/* ------------------------------------------------------------------------- *
|
||
*
|
||
* AppDomain interface
|
||
*
|
||
* ------------------------------------------------------------------------- */
|
||
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(3d6f5f63-7538-11d3-8d5b-00104b35e7ef),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugAppDomain : ICorDebugController
|
||
{
|
||
/*
|
||
* GetProcess returns the process containing the app domain
|
||
*/
|
||
|
||
HRESULT GetProcess([out] ICorDebugProcess **ppProcess);
|
||
|
||
/*
|
||
* EnumerateAssemblies enumerates all assemblies in the app domain
|
||
*
|
||
*/
|
||
|
||
HRESULT EnumerateAssemblies([out] ICorDebugAssemblyEnum **ppAssemblies);
|
||
|
||
/*
|
||
* GetModuleFromMetaDataInterface returns the ICorDebugModule with
|
||
* the given metadata interface.
|
||
*/
|
||
|
||
HRESULT GetModuleFromMetaDataInterface([in] IUnknown *pIMetaData,
|
||
[out] ICorDebugModule **ppModule);
|
||
|
||
/*
|
||
* EnumerateBreakpoints returns an enum (ICorDebugBreakpointEnum) of all active
|
||
* breakpoints in the app domain. This includes all types of breakpoints :
|
||
* function breakpoints, data breakpoints, etc.
|
||
*/
|
||
|
||
HRESULT EnumerateBreakpoints([out] ICorDebugBreakpointEnum **ppBreakpoints);
|
||
|
||
/*
|
||
* EnumerateSteppers returns an enum of all active steppers in the app domain.
|
||
*
|
||
*/
|
||
|
||
HRESULT EnumerateSteppers([out] ICorDebugStepperEnum **ppSteppers);
|
||
|
||
/*
|
||
* DEPRECATED. Always returns TRUE in V3 (attaching is process-wide).
|
||
*/
|
||
|
||
HRESULT IsAttached([out] BOOL *pbAttached);
|
||
|
||
|
||
/*
|
||
* GetName returns the name of the app domain.
|
||
*
|
||
* Usage pattern:
|
||
* *pcchName is always set to the length of pInputString (including NULL) in characters. This lets
|
||
* callers know the full size of buffer they'd need to allocate to get the full string.
|
||
*
|
||
* if (cchName == 0) then we're in "query" mode:
|
||
* This fails if szName is non-null or pcchName is null
|
||
* Else this function will set pcchName to let the caller know how large of a buffer to allocate
|
||
* and return S_OK.
|
||
*
|
||
* if (cchName != 0) then
|
||
* This fails if szName is null.
|
||
* Else this copies as much as can fit into szName (it will always null terminate szName) and returns S_OK.
|
||
* pcchName can be null. If it's non-null, we set it.
|
||
*
|
||
* The expected usage pattern is that a client will call once to get the size of a buffer needed for the name,
|
||
* allocate the buffer, and then call a 2nd time to fill in the buffer.
|
||
*
|
||
* The rest of the GetName() functions have the same semantics for the parameters unless otherwise noted.
|
||
*/
|
||
|
||
HRESULT GetName([in] ULONG32 cchName,
|
||
[out] ULONG32 *pcchName,
|
||
[out, size_is(cchName),
|
||
length_is(*pcchName)] WCHAR szName[]);
|
||
|
||
/*
|
||
* NOT YET IMPLEMENTED
|
||
*/
|
||
|
||
HRESULT GetObject([out] ICorDebugValue **ppObject);
|
||
|
||
/*
|
||
* DEPRECATED. This does nothing in V3. Attaching is process-wide.
|
||
*/
|
||
|
||
HRESULT Attach();
|
||
|
||
/*
|
||
* Get the ID of this app domain. The ID will be unique within the
|
||
* containing process.
|
||
*/
|
||
|
||
HRESULT GetID([out] ULONG32 *pId);
|
||
};
|
||
#pragma warning(pop)
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(096E81D5-ECDA-4202-83F5-C65980A9EF75),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugAppDomain2 : IUnknown
|
||
{
|
||
/*
|
||
* GetArrayOrPointerType returns an array, pointer, byref or function pointer type.
|
||
* elementType indicated the kind of type to be created and
|
||
* must be one of ELEMENT_TYPE_PTR, ELEMENT_TYPE_BYREF,
|
||
* ELEMENT_TYPE_ARRAY or ELEMENT_TYPE_SZARRAY. If used with
|
||
* ELEMENT_TYPE_PTR or ELEMENT_TYPE_BYREF then nRank must be zero.
|
||
*/
|
||
|
||
HRESULT GetArrayOrPointerType([in] CorElementType elementType,
|
||
[in] ULONG32 nRank,
|
||
[in] ICorDebugType *pTypeArg,
|
||
[out] ICorDebugType **ppType);
|
||
|
||
/*
|
||
* GetFunctionPointerType returns a function pointer type.
|
||
* This corresponds to ELEMENT_TYPE_FNPTR. The first type in the type arguments
|
||
* must be the return type and the remainder the argument types.
|
||
*/
|
||
|
||
HRESULT GetFunctionPointerType( [in] ULONG32 nTypeArgs,
|
||
[in, size_is(nTypeArgs)] ICorDebugType *ppTypeArgs[],
|
||
[out] ICorDebugType **ppType);
|
||
};
|
||
|
||
#pragma warning(push)
|
||
#pragma warning(disable:28718) /* disable warning 28718 for interface ICorDebugAssembly */
|
||
|
||
/* ------------------------------------------------------------------------- *
|
||
* Assembly interface
|
||
* An ICorDebugAssembly instance corresponds to a a managed assembly loaded
|
||
* into a specific AppDomain in the CLR. For assemblies shared between multiple
|
||
* AppDomains (eg. mscorlib), there will be a separate ICorDebugAssembly instance
|
||
* per AppDomain in which it is used.
|
||
* ------------------------------------------------------------------------- */
|
||
[
|
||
object,
|
||
local,
|
||
uuid(df59507c-d47a-459e-bce2-6427eac8fd06),
|
||
pointer_default(unique)
|
||
]
|
||
|
||
interface ICorDebugAssembly : IUnknown
|
||
{
|
||
/*
|
||
* GetProcess returns the process containing the assembly
|
||
*/
|
||
|
||
HRESULT GetProcess([out] ICorDebugProcess **ppProcess);
|
||
|
||
/*
|
||
* GetAppDomain returns the app domain containing the assembly.
|
||
*/
|
||
|
||
HRESULT GetAppDomain([out] ICorDebugAppDomain **ppAppDomain);
|
||
|
||
/*
|
||
* EnumerateModules enumerates all modules in the assembly
|
||
*
|
||
*/
|
||
|
||
HRESULT EnumerateModules([out] ICorDebugModuleEnum **ppModules);
|
||
|
||
/*
|
||
* NOT YET IMPLEMENTED
|
||
*/
|
||
|
||
HRESULT GetCodeBase([in] ULONG32 cchName,
|
||
[out] ULONG32 *pcchName,
|
||
[out, size_is(cchName),
|
||
length_is(*pcchName)] WCHAR szName[]);
|
||
|
||
/*
|
||
* GetName returns the full path and filename of the assembly.
|
||
* If the assembly has no filename (i.e. it is in-memory only),
|
||
* S_FALSE is returned, and a fabricated string is stored into szName.
|
||
*/
|
||
|
||
HRESULT GetName([in] ULONG32 cchName,
|
||
[out] ULONG32 *pcchName,
|
||
[out, size_is(cchName),
|
||
length_is(*pcchName)] WCHAR szName[]);
|
||
};
|
||
#pragma warning(pop)
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(426d1f9e-6dd4-44c8-aec7-26cdbaf4e398),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugAssembly2 : IUnknown
|
||
{
|
||
/*
|
||
* IsFullyTrusted sets a flag indicating whether the assembly has
|
||
* been granted full trust by the runtime security system.
|
||
* This may return CORDBG_E_NOTREADY if the security policy for
|
||
* the assembly has not yet been resolved (eg. no code in the
|
||
* assembly has been run yet).
|
||
*/
|
||
HRESULT IsFullyTrusted( [out] BOOL *pbFullyTrusted );
|
||
};
|
||
|
||
/* ------------------------------------------------------------------------- *
|
||
* Process interface
|
||
* ------------------------------------------------------------------------- */
|
||
|
||
#pragma warning(push)
|
||
#pragma warning(disable:28718) /* suppress warning 28718 for interface ICorDebugProcess */
|
||
|
||
/*
|
||
* ICorDebugProcess represents a process running some managed code.
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(3d6f5f64-7538-11d3-8d5b-00104b35e7ef),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugProcess : ICorDebugController
|
||
{
|
||
/*
|
||
* GetID returns the OS ID of the process.
|
||
*/
|
||
|
||
HRESULT GetID([out] DWORD *pdwProcessId);
|
||
|
||
/*
|
||
* GetHandle returns a handle to the process. This handle is owned
|
||
* by the debugging API; the debugger should duplicate it before
|
||
* using it.
|
||
*/
|
||
|
||
HRESULT GetHandle([out] HPROCESS *phProcessHandle);
|
||
|
||
/*
|
||
* GetThread returns the ICorDebugThread with the given OS Id.
|
||
*
|
||
* Note that eventually there will not be a one to one correspondence
|
||
* between OS threads and runtime threads, so this entry point will
|
||
* go away.
|
||
*/
|
||
|
||
HRESULT GetThread([in] DWORD dwThreadId, [out] ICorDebugThread **ppThread);
|
||
|
||
/*
|
||
* NOT YET IMPLEMENTED
|
||
*/
|
||
|
||
HRESULT EnumerateObjects([out] ICorDebugObjectEnum **ppObjects);
|
||
|
||
/*
|
||
* IsTransitionStub tests whether an address is inside of a transition stub
|
||
* which will cause a transition to managed code. This can be used by
|
||
* unmanaged stepping code to decide when to return stepping control to
|
||
* the managed stepper.
|
||
*
|
||
* Note that, tentatively, these stubs may also be able to be identified
|
||
* ahead of time by looking at information in the PE file.
|
||
*
|
||
*/
|
||
|
||
HRESULT IsTransitionStub([in] CORDB_ADDRESS address,
|
||
[out] BOOL *pbTransitionStub);
|
||
|
||
|
||
/*
|
||
* IsOSSuspended returns whether or not the thread has been
|
||
* suspended as part of the debugger logic of stopping the process.
|
||
* (that is, it has had its Win32 suspend count incremented by
|
||
* one.) The debugger UI may want to take this into account if
|
||
* it shows the user the OS suspend count of the thread.
|
||
*
|
||
* This function only makes sense in the context of
|
||
* unmanaged debugging - during managed debugging threads are not
|
||
* OS suspended. (They are cooperatively suspended.)
|
||
*/
|
||
|
||
HRESULT IsOSSuspended([in] DWORD threadID, [out] BOOL *pbSuspended);
|
||
|
||
/*
|
||
* GetThreadContext returns the context for the given thread. The
|
||
* debugger should call this function rather than the Win32
|
||
* GetThreadContext, because the thread may actually be in a "hijacked"
|
||
* state where its context has been temporarily changed.
|
||
*
|
||
* This should only be used on when a thread is in native code. Use ICorDebugRegisterSet
|
||
* for threads in managed code.
|
||
*
|
||
* The data returned is a CONTEXT structure for the current platform.
|
||
* (CONTEXT is typically declared in winnt.h) Just as with a call
|
||
* to Win32's GetThreadContext, the caller should initialize the
|
||
* CONTEXT struct before calling.
|
||
*
|
||
*/
|
||
|
||
HRESULT GetThreadContext([in] DWORD threadID,
|
||
[in] ULONG32 contextSize,
|
||
[in, out, length_is(contextSize),
|
||
size_is(contextSize)] BYTE context[]);
|
||
|
||
/*
|
||
* SetThreadContext sets the context for the given thread. The
|
||
* debugger should call this function rather than the Win32
|
||
* SetThreadContext, because the thread may actually be in a "hijacked"
|
||
* state where its context has been temporarily changed.
|
||
*
|
||
* This should only be used on when a thread is in native code. Use ICorDebugRegisterSet
|
||
* for threads in managed code.
|
||
*
|
||
* This should never be needed to modify the context of a thread during an oob-debug
|
||
* event.
|
||
*
|
||
* The data passed should be a CONTEXT structure for the current platform.
|
||
* (CONTEXT is typically declared in winnt.h)
|
||
*
|
||
* This is a dangerous call which can corrupt the runtime if used
|
||
* improperly.
|
||
*
|
||
*/
|
||
|
||
HRESULT SetThreadContext([in] DWORD threadID,
|
||
[in] ULONG32 contextSize,
|
||
[in, length_is(contextSize),
|
||
size_is(contextSize)] BYTE context[]);
|
||
|
||
/*
|
||
* ReadMemory reads memory from the process.
|
||
* This is primarily intended to be used by interop-debugging to inspect memory
|
||
* regions used by the unmanaged portion of the debuggee.
|
||
*
|
||
* This can also be used to read IL and native jitted code.
|
||
* Any managed breakpoints will be automatically stripped from the returned buffer.
|
||
* No adjustments will be made for Native breakpoints set by ICorDebugProcess2::SetUnmanagedBreakpoint
|
||
*
|
||
* No caching of process memory is peformed.
|
||
* These parameters have the same semantics as kernel32!ReadProcessMemory.
|
||
* The entire range must be read for the function to return success.
|
||
*/
|
||
|
||
HRESULT ReadMemory([in] CORDB_ADDRESS address, [in] DWORD size,
|
||
[out, size_is(size), length_is(size)] BYTE buffer[],
|
||
[out] SIZE_T *read);
|
||
|
||
/*
|
||
* WriteMemory writes memory in the process.
|
||
* In v2.0, Native debuggers should *not* use this to inject breakpoints
|
||
* into the instruction stream. Use ICorDebugProcess2::SetUnamangedBreakpoint
|
||
* instead.
|
||
*
|
||
* This is a dangerous call which can corrupt the runtime if used
|
||
* improperly. It is highly recommended that this is only used outside
|
||
* of managed code.
|
||
*
|
||
* These parameters have the same semantics as kernel32!WriteProcessMemory.
|
||
*/
|
||
|
||
HRESULT WriteMemory([in] CORDB_ADDRESS address, [in] DWORD size,
|
||
[in, size_is(size)] BYTE buffer[],
|
||
[out]SIZE_T *written);
|
||
|
||
|
||
/*
|
||
* ClearCurrentException clears the current unmanaged exception on
|
||
* the given thread. Call this before calling Continue when a
|
||
* thread has reported an unmanaged exception that should be
|
||
* ignored by the debuggee.
|
||
*
|
||
* This will clear both the outstanding IB and OOB events on the given thread.
|
||
* Out-of-band Breakpoint and single-step exceptions are automatically cleared.
|
||
*
|
||
* See ICorDebugThread2::InterceptCurrentException for continuing managed exceptions.
|
||
*
|
||
*/
|
||
|
||
HRESULT ClearCurrentException([in] DWORD threadID);
|
||
|
||
/*
|
||
* EnableLogMessages enables/disables sending of log messages to the
|
||
* debugger for logging.
|
||
* This is only valid after the CreateProcess callback.
|
||
*
|
||
*/
|
||
|
||
HRESULT EnableLogMessages([in]BOOL fOnOff);
|
||
|
||
/*
|
||
* ModifyLogSwitch modifies the specified switch's severity level.
|
||
* This is only valid after the CreateProcess callback.
|
||
*
|
||
*/
|
||
HRESULT ModifyLogSwitch([in] WCHAR *pLogSwitchName,
|
||
[in]LONG lLevel);
|
||
|
||
/*
|
||
* EnumerateAppDomains enumerates all app domains in the process.
|
||
* This can be used before the CreateProcess callback.
|
||
*
|
||
*/
|
||
|
||
HRESULT EnumerateAppDomains([out] ICorDebugAppDomainEnum **ppAppDomains);
|
||
|
||
/*
|
||
* NOT YET IMPLEMENTED
|
||
*/
|
||
|
||
HRESULT GetObject([out] ICorDebugValue **ppObject);
|
||
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
|
||
HRESULT ThreadForFiberCookie([in] DWORD fiberCookie,
|
||
[out] ICorDebugThread **ppThread);
|
||
|
||
/*
|
||
* Returns the OS thread id of the debugger's internal helper thread.
|
||
* During managed/unmanaged debugging, it is the debugger's
|
||
* responsibility to ensure that the thread with this ID remains running
|
||
* if it hits a breakpoint placed by the debugger. A debugger may also
|
||
* wish to hide this thread from the user.
|
||
*
|
||
* If there is no helper thread in the process yet, then this method
|
||
* will return zero as the thread id.
|
||
*
|
||
* Note: you cannot cache this value. The ID of the helper thread may
|
||
* change over time, so this value must be re-queried at every stopping
|
||
* event.
|
||
*
|
||
* Note: this value will be correct on every unmanaged CreateThread event.
|
||
* This will allow a debugger to determine the TID of the helper thread
|
||
* and hide it from the user. A thread identified as a helper thread during
|
||
* an unmanaged CreateThread event will never run managed user code.
|
||
*/
|
||
|
||
HRESULT GetHelperThreadID([out] DWORD *pThreadID);
|
||
};
|
||
#pragma warning(pop)
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(AD1B3588-0EF0-4744-A496-AA09A9F80371),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugProcess2 : IUnknown
|
||
{
|
||
|
||
/*
|
||
* Return a ICorDebugThread2 interface given a TASKID
|
||
* Host can set TASKID using ICLRTask::SetTaskIdentifier
|
||
*/
|
||
HRESULT GetThreadForTaskID(
|
||
[in] TASKID taskid,
|
||
[out] ICorDebugThread2 **ppThread);
|
||
|
||
|
||
/*
|
||
* Returns the version of the runtime the debugee process is running.
|
||
*/
|
||
HRESULT GetVersion([out] COR_VERSION* version);
|
||
|
||
/*
|
||
* Set an unmanaged breakpoint at the given native address. If the address is within
|
||
* the runtime, the breakpoint will be ignored.
|
||
* This allows the CLR to avoid dispatching out-of-band breakpoints for breakpoints
|
||
* set by the debugger.
|
||
* buffer[] returns the opcode at the address that is replaced by the breakpoint.
|
||
*/
|
||
|
||
HRESULT SetUnmanagedBreakpoint([in] CORDB_ADDRESS address,
|
||
[in] ULONG32 bufsize,
|
||
[out, size_is(bufsize), length_is(*bufLen)] BYTE buffer[],
|
||
[out] ULONG32 * bufLen);
|
||
|
||
/*
|
||
* Remove a breakpoint set by SetUnmanagedBreakpoint.
|
||
*/
|
||
HRESULT ClearUnmanagedBreakpoint([in] CORDB_ADDRESS address);
|
||
|
||
|
||
/*
|
||
* SetDesiredNGENCompilerFlags specifies the set of flags that must be set in a pre-JITted
|
||
* image in order for the runtime to load that image into this app domain. If no such image exists,
|
||
* the runtime will load the IL and JIT instead. The flags set by this function are just used to select the
|
||
* correct pre-JITted image; if no suitable image is found the debugger will still need to use
|
||
* ICorDebugModule2::SetJITCompilerFlags to set the flags as desired for JIT.
|
||
*
|
||
* This function must be called during the CreateProcess callback.
|
||
* Attempts to call it after this callback has been delivered will fail.
|
||
*/
|
||
HRESULT SetDesiredNGENCompilerFlags( [in] DWORD pdwFlags );
|
||
|
||
/*
|
||
* GetDesiredNGENCompilerFlags gets the set of flags that must be set in a pre-JITted image in order
|
||
* for the runtime to load that image into this process.
|
||
*/
|
||
HRESULT GetDesiredNGENCompilerFlags( [out] DWORD *pdwFlags );
|
||
|
||
|
||
/*
|
||
* Gets an ICorDebugReferenceValue object from a raw GC handle value.
|
||
*
|
||
* handle is the IntPtr within a GCHandle. Do not confuse
|
||
* this with a GC reference value. This is a potentially dangerous API and may
|
||
* corrupt both the debugger and debuggee if a bogus handle is passed in.
|
||
* This API does not necessarily validate that the handle is valid.
|
||
*
|
||
* The ICorDebugReferenceValue will behave much like a normal reference. It will
|
||
* be neutered on the next continue; the lifetime of the target object will
|
||
* not be affected by the existence of the ReferenceValue.
|
||
*/
|
||
HRESULT GetReferenceValueFromGCHandle( [in] UINT_PTR handle,
|
||
[out] ICorDebugReferenceValue **pOutValue);
|
||
|
||
};
|
||
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(2EE06488-C0D4-42B1-B26D-F3795EF606FB),
|
||
pointer_default(unique)
|
||
]
|
||
|
||
interface ICorDebugProcess3 : IUnknown
|
||
{
|
||
/* Enables (or disables) custom debugger notifications of a specified
|
||
* type (which implements ICustomDebuggerNotification).
|
||
* When this has been enabled, calls to
|
||
* System.Diagnostics.Debugger.CustomNotification with a data argument
|
||
* of the specified class will trigger a CustomNotification callback.
|
||
* Notifications are disabled by default and the debugger must opt-into
|
||
* any notification types it knows of and wishes to handle.
|
||
* Since ICorDebugClass is scoped by appdomains, the debugger needs to
|
||
* call this API for every appdomain in the process if it<69>s interested in
|
||
* receiving the notification across the entire process.
|
||
*/
|
||
|
||
HRESULT SetEnableCustomNotification(ICorDebugClass * pClass, BOOL fEnable);
|
||
}
|
||
|
||
|
||
/* ------------------------------------------------------------------------- *
|
||
* Breakpoint interface
|
||
* ------------------------------------------------------------------------- */
|
||
|
||
/*
|
||
* ICorDebugBreakpoint represents a breakpoint; either a breakpoint
|
||
* set in a function, or a watchpoint set on a value.
|
||
*
|
||
* Note that breakpoints have no direct support for condition
|
||
* expressions. The debugger must implement this functionality on top of
|
||
* this interface if desired.
|
||
*
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCAE8-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugBreakpoint : IUnknown
|
||
{
|
||
/*
|
||
* Sets the active state of the breakpoint
|
||
*/
|
||
HRESULT Activate([in] BOOL bActive);
|
||
|
||
/*
|
||
* Returns whether the breakpoint is active.
|
||
*/
|
||
HRESULT IsActive([out] BOOL *pbActive);
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCAE9-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugFunctionBreakpoint : ICorDebugBreakpoint
|
||
{
|
||
/*
|
||
* Returns the function on which this breakpoint is set
|
||
*/
|
||
HRESULT GetFunction([out] ICorDebugFunction **ppFunction);
|
||
|
||
/*
|
||
* Returns the offset of this breakpoint within the function
|
||
*/
|
||
HRESULT GetOffset([out] ULONG32 *pnOffset);
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCAEA-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugModuleBreakpoint : ICorDebugBreakpoint
|
||
{
|
||
/*
|
||
* Returns the module on which this breakpoint is set.
|
||
*/
|
||
HRESULT GetModule([out] ICorDebugModule **ppModule);
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCAEB-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugValueBreakpoint : ICorDebugBreakpoint
|
||
{
|
||
/*
|
||
* Gets the value on which this breakpoint is set.
|
||
*/
|
||
HRESULT GetValue([out] ICorDebugValue **ppValue);
|
||
};
|
||
|
||
/* ------------------------------------------------------------------------- *
|
||
* Stepper interface
|
||
* ------------------------------------------------------------------------- */
|
||
|
||
/*
|
||
* A Stepper object represents a stepping operation being performed by
|
||
* the debugger. Note that there can be more than one stepper per
|
||
* thread; for instance a breakpoint may be hit in the midst of a
|
||
* stepping over a function, and the user may wish to start a new
|
||
* stepping operation inside that function. (Note that it is up to the
|
||
* debugger how to handle this; it may want to cancel the original
|
||
* stepping operation, or nest them. This API allows either behavior.)
|
||
*
|
||
* Also, a stepper may migrate between threads if a cross-thread
|
||
* marshalled call is made by the EE.
|
||
*
|
||
* This object serves several purposes. Its serves as an identifer between a
|
||
* step command issued and the completion of that command. It also
|
||
* provides a central interface to encapsulate all of the stepping
|
||
* that can be performed. Finally it provides a way to prematurely
|
||
* cancel a stepping operation.
|
||
*
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCAEC-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugStepper : IUnknown
|
||
{
|
||
/*
|
||
* IsActive returns whether or not the stepper is active, that is, whether
|
||
* it is currently stepping.
|
||
*
|
||
* Any step action remains active until StepComplete is called. Note that
|
||
* this automatically deactivates the stepper.
|
||
*
|
||
* A stepper may also be deactivated prematurely by calling
|
||
* Deactivate before a callback condition is reached.
|
||
*/
|
||
|
||
HRESULT IsActive([out] BOOL *pbActive);
|
||
|
||
/*
|
||
* Deactivate causes a stepper to cancel the last stepping command it
|
||
* received. A new stepping command may then be issued.
|
||
*/
|
||
|
||
HRESULT Deactivate();
|
||
|
||
/*
|
||
* SetInterceptMask controls which intercept code will be stepped
|
||
* into by the stepper. If the bit for an interceptor is set, the
|
||
* stepper will complete with reason STEPPER_INTERCEPT when the
|
||
* given type of intercept occurs. If the bit is cleared, the
|
||
* intercepting code will be skipped.
|
||
*
|
||
* Note that SetInterceptMask may have unforeseen interactions
|
||
* with SetUnmappedStopMask (from the user's point of view). For
|
||
* example, if the only visible (ie, non internal) portion of class
|
||
* init code lacks mapping info (STOP_NO_MAPPING_INFO) and
|
||
* STOP_NO_MAPPING_INFO isn't set, then we'll step over the class init.
|
||
*
|
||
* By default, only INTERCEPT_NONE will be used.
|
||
*/
|
||
|
||
typedef enum CorDebugIntercept
|
||
{
|
||
INTERCEPT_NONE = 0x0 ,
|
||
INTERCEPT_CLASS_INIT = 0x01,
|
||
INTERCEPT_EXCEPTION_FILTER = 0x02,
|
||
INTERCEPT_SECURITY = 0x04,
|
||
INTERCEPT_CONTEXT_POLICY = 0x08,
|
||
INTERCEPT_INTERCEPTION = 0x10,
|
||
INTERCEPT_ALL = 0xffff
|
||
} CorDebugIntercept;
|
||
|
||
HRESULT SetInterceptMask([in] CorDebugIntercept mask);
|
||
|
||
/*
|
||
* SetUnmappedStopMask controls whether the stepper
|
||
* will stop in jitted code which is not mapped to IL.
|
||
*
|
||
* If the given flag is set, then that type of unmapped code
|
||
* will be stopped in. Otherwise stepping transparently continues.
|
||
*
|
||
* It should be noted that if one doesn't use a stepper to enter a
|
||
* method (for example, the main() method of C++), then one
|
||
* won't neccessarily step over prologs,etc.
|
||
*
|
||
* By default, STOP_OTHER_UNMAPPED will be used.
|
||
*
|
||
* STOP_UNMANAGED is only valid w/ interop debugging.
|
||
*/
|
||
|
||
typedef enum CorDebugUnmappedStop
|
||
{
|
||
STOP_NONE = 0x0,
|
||
STOP_PROLOG = 0x01,
|
||
STOP_EPILOG = 0x02,
|
||
STOP_NO_MAPPING_INFO = 0x04,
|
||
STOP_OTHER_UNMAPPED = 0x08,
|
||
STOP_UNMANAGED = 0x10,
|
||
|
||
STOP_ALL = 0xffff,
|
||
|
||
} CorDebugUnmappedStop;
|
||
|
||
HRESULT SetUnmappedStopMask([in] CorDebugUnmappedStop mask);
|
||
|
||
/*
|
||
* Step is called when a thread is to be single stepped. The step
|
||
* will complete at the next managed instruction executed by the
|
||
* EE in the stepper's frame.
|
||
*
|
||
* If bStepIn is TRUE, any function calls made during the step
|
||
* will be stepped into. Otherwise they will be skipped.
|
||
*
|
||
* If Step is called on a stepper which is not in managed code,
|
||
* the step will complete when the next managed code is executed
|
||
* by the thread. (if bStepIn is FALSE, it will only complete
|
||
* when managed code is returned to, not when it is stepped into.)
|
||
*/
|
||
|
||
HRESULT Step([in] BOOL bStepIn);
|
||
|
||
/*
|
||
* StepRange works just like Step, except it will not complete
|
||
* until code outside the given range is reached. This can be
|
||
* more efficient than stepping one instruction at a time.
|
||
*
|
||
* Ranges are specified as a list of offset pairs [start, end)
|
||
* (note that end is exclusive) from the start of the stepper's
|
||
* frame's code.
|
||
*
|
||
* Ranges are in relative to the IL code of a method. Call
|
||
* SetRangeIL(FALSE) to specify ranges relative to the native code
|
||
* of a method.
|
||
*/
|
||
|
||
typedef struct COR_DEBUG_STEP_RANGE
|
||
{
|
||
ULONG32 startOffset, endOffset;
|
||
} COR_DEBUG_STEP_RANGE;
|
||
|
||
HRESULT StepRange([in] BOOL bStepIn,
|
||
[in,size_is(cRangeCount)] COR_DEBUG_STEP_RANGE ranges[],
|
||
[in] ULONG32 cRangeCount);
|
||
|
||
/*
|
||
* A StepOut operation will complete after the current frame is
|
||
* returned from normally and the previous frame is reactivated.
|
||
*
|
||
* If this is called when in unmanaged code, the step will complete
|
||
* when the calling managed code is returned to.
|
||
*
|
||
* In v2.0, we explicitly forbid StepOut with the STOP_UNMANAGED mask
|
||
* and will fail that. Interop debuggers must do step-out-to-native
|
||
* themselves.
|
||
*/
|
||
|
||
HRESULT StepOut();
|
||
|
||
/*
|
||
* SetRangeIL is used to set whether the ranges passed StepRange are
|
||
* relative to the IL code or the native code for the method being
|
||
* stepped in.
|
||
*
|
||
* By default the range is in IL.
|
||
*/
|
||
|
||
HRESULT SetRangeIL([in] BOOL bIL);
|
||
};
|
||
|
||
/*
|
||
* ICorDebugStepper2 exposes JMC functionality.
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(C5B6E9C3-E7D1-4a8e-873B-7F047F0706F7),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugStepper2 : IUnknown
|
||
{
|
||
HRESULT SetJMC([in] BOOL fIsJMCStepper);
|
||
}
|
||
|
||
/* ------------------------------------------------------------------------- *
|
||
* Program state object interfaces
|
||
* ------------------------------------------------------------------------- */
|
||
|
||
/*
|
||
* ICorDebugRegisterSet
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCB0B-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugRegisterSet : IUnknown
|
||
{
|
||
typedef enum CorDebugRegister
|
||
{
|
||
// registers (potentially) available on all architectures
|
||
// Note that these overlap with the architecture-specific
|
||
// registers
|
||
//
|
||
// NOTE: On IA64, REGISTER_FRAME_POINTER represents the BSP register.
|
||
|
||
REGISTER_INSTRUCTION_POINTER = 0,
|
||
REGISTER_STACK_POINTER,
|
||
REGISTER_FRAME_POINTER,
|
||
|
||
|
||
// X86 registers
|
||
|
||
REGISTER_X86_EIP = 0,
|
||
REGISTER_X86_ESP,
|
||
REGISTER_X86_EBP,
|
||
|
||
REGISTER_X86_EAX,
|
||
REGISTER_X86_ECX,
|
||
REGISTER_X86_EDX,
|
||
REGISTER_X86_EBX,
|
||
|
||
REGISTER_X86_ESI,
|
||
REGISTER_X86_EDI,
|
||
|
||
REGISTER_X86_FPSTACK_0,
|
||
REGISTER_X86_FPSTACK_1,
|
||
REGISTER_X86_FPSTACK_2,
|
||
REGISTER_X86_FPSTACK_3,
|
||
REGISTER_X86_FPSTACK_4,
|
||
REGISTER_X86_FPSTACK_5,
|
||
REGISTER_X86_FPSTACK_6,
|
||
REGISTER_X86_FPSTACK_7,
|
||
|
||
|
||
// AMD64 registers
|
||
|
||
REGISTER_AMD64_RIP = 0,
|
||
REGISTER_AMD64_RSP,
|
||
REGISTER_AMD64_RBP,
|
||
|
||
REGISTER_AMD64_RAX,
|
||
REGISTER_AMD64_RCX,
|
||
REGISTER_AMD64_RDX,
|
||
REGISTER_AMD64_RBX,
|
||
|
||
REGISTER_AMD64_RSI,
|
||
REGISTER_AMD64_RDI,
|
||
|
||
REGISTER_AMD64_R8,
|
||
REGISTER_AMD64_R9,
|
||
REGISTER_AMD64_R10,
|
||
REGISTER_AMD64_R11,
|
||
REGISTER_AMD64_R12,
|
||
REGISTER_AMD64_R13,
|
||
REGISTER_AMD64_R14,
|
||
REGISTER_AMD64_R15,
|
||
|
||
// Xmm FP
|
||
|
||
REGISTER_AMD64_XMM0,
|
||
REGISTER_AMD64_XMM1,
|
||
REGISTER_AMD64_XMM2,
|
||
REGISTER_AMD64_XMM3,
|
||
REGISTER_AMD64_XMM4,
|
||
REGISTER_AMD64_XMM5,
|
||
REGISTER_AMD64_XMM6,
|
||
REGISTER_AMD64_XMM7,
|
||
REGISTER_AMD64_XMM8,
|
||
REGISTER_AMD64_XMM9,
|
||
REGISTER_AMD64_XMM10,
|
||
REGISTER_AMD64_XMM11,
|
||
REGISTER_AMD64_XMM12,
|
||
REGISTER_AMD64_XMM13,
|
||
REGISTER_AMD64_XMM14,
|
||
REGISTER_AMD64_XMM15,
|
||
|
||
|
||
// IA64 registers
|
||
|
||
REGISTER_IA64_BSP = REGISTER_FRAME_POINTER,
|
||
|
||
// To get a particular general register, add the register number
|
||
// to REGISTER_IA64_R0. The same also goes for floating point
|
||
// registers.
|
||
//
|
||
// For example, if you need REGISTER_IA64_R83,
|
||
// use REGISTER_IA64_R0 + 83.
|
||
REGISTER_IA64_R0 = REGISTER_IA64_BSP + 1,
|
||
REGISTER_IA64_F0 = REGISTER_IA64_R0 + 128,
|
||
|
||
|
||
// other architectures here
|
||
|
||
} CorDebugRegister;
|
||
|
||
/*
|
||
* GetRegistersAvailable returns a mask indicating which registers
|
||
* are available in the given register set. Registers may be unavailable
|
||
* if their value is undeterminable for the given situation. The returned
|
||
* word contains a bit for each register (1 << register index), which will
|
||
* be 1 if the register is available or 0 if it is not.
|
||
*/
|
||
|
||
HRESULT GetRegistersAvailable([out] ULONG64 *pAvailable);
|
||
|
||
/*
|
||
* GetRegisters returns an array of register values corresponding
|
||
* to the given mask. The registers which have their bit set in
|
||
* the mask will be packed into the resulting array. (No room is
|
||
* assigned in the array for registers whose mask bit is not set.)
|
||
* Thus, the size of the array should be equal to the number of
|
||
* 1's in the mask.
|
||
*
|
||
* If an unavailable register is indicated by the mask, an indeterminate
|
||
* value will be returned for the corresponding register.
|
||
*
|
||
* registerBufferCount should indicate number of elements in the
|
||
* buffer to receive the register values. If it is too small for
|
||
* the number of registers indicated by the mask, the higher
|
||
* numbered registers will be truncated from the set. Or, if it
|
||
* is too large, the unused registerBuffer elements will be
|
||
* unmodified. */
|
||
|
||
HRESULT GetRegisters([in] ULONG64 mask, [in] ULONG32 regCount,
|
||
[out, size_is(regCount), length_is(regCount)]
|
||
CORDB_REGISTER regBuffer[]);
|
||
|
||
/*
|
||
* NOT YET IMPLEMENTED
|
||
*/
|
||
|
||
HRESULT SetRegisters([in] ULONG64 mask,
|
||
[in] ULONG32 regCount,
|
||
[in, size_is(regCount)] CORDB_REGISTER regBuffer[]);
|
||
|
||
/*
|
||
* GetThreadContext returns the context for the given thread. The
|
||
* debugger should call this function rather than the Win32
|
||
* GetThreadContext, because the thread may actually be in a "hijacked"
|
||
* state where its context has been temporarily changed.
|
||
*
|
||
* The data returned is a CONTEXT structure for the current platform.
|
||
*
|
||
* For non-leaf frames, clients should check which registers are valid by
|
||
* using GetRegistersAvailable.
|
||
*
|
||
*/
|
||
|
||
HRESULT GetThreadContext([in] ULONG32 contextSize,
|
||
[in, out, length_is(contextSize),
|
||
size_is(contextSize)] BYTE context[]);
|
||
|
||
/*
|
||
* Not implemented in v2.0. It is too dangerous to manipulate the context of
|
||
* threads in Managed code. Use other high level operations (like SetIp,
|
||
* ICorDebugValue::SetValue) instead.
|
||
*
|
||
*/
|
||
|
||
HRESULT SetThreadContext([in] ULONG32 contextSize,
|
||
[in, length_is(contextSize),
|
||
size_is(contextSize)] BYTE context[]);
|
||
}
|
||
|
||
/*
|
||
* ICorDebugRegisterSet2 is an extension for hardward platforms with more
|
||
* than 64 registers, since ICorDebugRegisterSet::GetRegisters() only
|
||
* recognizes a 64-bit mask.
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(6DC7BA3F-89BA-4459-9EC1-9D60937B468D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugRegisterSet2 : IUnknown
|
||
{
|
||
/*
|
||
* Given a CorDebugRegister value, its position in the mask is determined as
|
||
* follows:
|
||
*
|
||
* 1) (value >> 3) is used to index the array of BYTEs, and
|
||
* 2) (value & 7) (the least significant three bits) represents the bit position
|
||
* within the indexed BYTE, where bit 0 is the least significant bit.
|
||
*
|
||
* Or, in code:
|
||
*
|
||
* #define REGISTER_IA64_MAX REGISTER_IA64_F0 + 128
|
||
* #define MAX_MASK_COUNT ((REGISTER_IA64_MAX + 7) >> 3)
|
||
* #define SET_BIT_MASK(_mask, _reg) _mask[(_reg) >> 3] |= (1 << ((_reg) & 7))
|
||
* #define RESET_BIT_MASK(_mask, _reg) _mask[(_reg) >> 3] &= ~(1 << ((_reg) & 7))
|
||
* #define IS_SET_BIT_MASK(_mask, _reg) _mask[(_reg) >> 3] & (1 << ((_reg) & 7))
|
||
*
|
||
* CorDebugRegister value = <some value>;
|
||
* BYTE pAvailable[MAX_MASK_COUNT];
|
||
*
|
||
* GetRegistersAvailable(MAX_MASK_COUNT, pAvailable);
|
||
* ASSERT(value < REGISTER_IA64_MAX);
|
||
* IS_SET_BIT_MASK(pAvailable, value);
|
||
*/
|
||
|
||
HRESULT GetRegistersAvailable([in] ULONG32 numChunks,
|
||
[out, size_is(numChunks)] BYTE availableRegChunks[]);
|
||
|
||
HRESULT GetRegisters([in] ULONG32 maskCount,
|
||
[in, size_is(maskCount)] BYTE mask[],
|
||
[in] ULONG32 regCount,
|
||
[out, size_is(regCount)] CORDB_REGISTER regBuffer[]);
|
||
|
||
HRESULT SetRegisters([in] ULONG32 maskCount,
|
||
[in, size_is(maskCount)] BYTE mask[],
|
||
[in] ULONG32 regCount,
|
||
[in, size_is(regCount)] CORDB_REGISTER regBuffer[]);
|
||
}
|
||
|
||
/*
|
||
* ICorDebugThread represents a thread in the process. The lifetime of a
|
||
* thread object is equal to the lifetime of the thread it represents.
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(938c6d66-7fb6-4f69-b389-425b8987329b),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugThread : IUnknown
|
||
{
|
||
/*
|
||
* GetProcess returns the process of which this thread is a part.
|
||
*/
|
||
|
||
HRESULT GetProcess([out] ICorDebugProcess **ppProcess);
|
||
|
||
/*
|
||
* GetID returns the current OS ID of the active part of the thread.
|
||
* Note that this may theoretically change as the process executes,
|
||
* and even be different for different parts of the thread.
|
||
*/
|
||
|
||
HRESULT GetID([out] DWORD *pdwThreadId);
|
||
|
||
/*
|
||
* GetHandle returns the current Handle of the active part of the thread.
|
||
* Note that this may theoretically change as the process executes,
|
||
* and even be different for different parts of the thread.
|
||
*
|
||
* This handle is owned by the debugging API. The debugger should duplicate
|
||
* it before using it.
|
||
*/
|
||
|
||
HRESULT GetHandle([out] HTHREAD *phThreadHandle);
|
||
|
||
/*
|
||
* GetAppDomain returns the app domain which the thread is currently
|
||
* executing in.
|
||
*/
|
||
|
||
HRESULT GetAppDomain([out] ICorDebugAppDomain **ppAppDomain);
|
||
|
||
/*
|
||
* SetDebugState sets the current debug state of the thread.
|
||
* (The "current debug state"
|
||
* represents the debug state if the process were to be continued,
|
||
* not the actual current state.)
|
||
*
|
||
* The normal value for this is THREAD_RUNNING. Only the debugger
|
||
* can affect the debug state of a thread. Debug states do
|
||
* last across continues, so if you want to keep a thread
|
||
* THREAD_SUSPENDed over mulitple continues, you can set it once
|
||
* and thereafter not have to worry about it.
|
||
*
|
||
* Suspending threads and resuming the process can cause deadlocks, though it's
|
||
* usually unlikely. This is an intrinisc quality of threads and processes and is by-design.
|
||
* A debugger can async break and resume the threads to break the deadlock.
|
||
*
|
||
* If the thread's user state includes USER_UNSAFE_POINT, then the thread may block a GC.
|
||
* This means the suspended thread has a mcuh higher chance of causing a deadlock.
|
||
*
|
||
* This may not affect debug events already queued. Thus a debugger should drain the entire
|
||
* event queue (via calling HasQueuedCallbacks) before suspending or resuming threads. Else it
|
||
* may get events on a thread that it believes it has already suspended.
|
||
*
|
||
*/
|
||
|
||
HRESULT SetDebugState([in] CorDebugThreadState state);
|
||
|
||
/*
|
||
* GetDebugState returns the current debug state of the thread.
|
||
* (If the process is currently stopped, the "current debug state"
|
||
* represents the debug state if the process were to be continued,
|
||
* not the actual current state.)
|
||
*/
|
||
|
||
HRESULT GetDebugState([out] CorDebugThreadState *pState);
|
||
|
||
/*
|
||
* GetUserState returns the user state of the thread, that is, the state
|
||
* which it has when the program being debugged examines it.
|
||
* A thread may have multiple state bits set.
|
||
*/
|
||
|
||
typedef enum CorDebugUserState
|
||
{
|
||
USER_STOP_REQUESTED = 0x01,
|
||
USER_SUSPEND_REQUESTED = 0x02,
|
||
USER_BACKGROUND = 0x04,
|
||
USER_UNSTARTED = 0x08,
|
||
USER_STOPPED = 0x10,
|
||
USER_WAIT_SLEEP_JOIN = 0x20,
|
||
USER_SUSPENDED = 0x40,
|
||
|
||
// An "unsafe point" is a place where the thread may block a Garbage Collection (GC).
|
||
// Debug events may be dispatched from unsafe points, but suspending a thread at
|
||
// an unsafe spot will very likely cause a deadlock (until the thread is resumed).
|
||
// This is a function of the thread's IP and the available GC info. The exact details
|
||
// of what is safe and unsafe is unspecified and highly determined by jit/gc implementation details.
|
||
USER_UNSAFE_POINT = 0x80,
|
||
} CorDebugUserState;
|
||
|
||
HRESULT GetUserState([out] CorDebugUserState *pState);
|
||
|
||
/*
|
||
* GetCurrentException returns the exception object which is
|
||
* currently being thrown by the thread. This will exist from the time the exception
|
||
* is thrown until the end of the catch block. That range will include filters
|
||
* and finallys.
|
||
*
|
||
* FuncEval will clear out the exception object on setup and restore it on completion.
|
||
*
|
||
* Exceptions can be nested (eg, if an exception is thrown in filter or a func-eval),
|
||
* so there may be multiple outstanding exceptions on a single thread.
|
||
* This returns the most current exception.
|
||
*
|
||
* The exception object and type may change throughout the life of the exception. For example, an
|
||
* exception of type X may be thrown, but then the CLR may run out of memory and promote
|
||
* that to an OutOfMemory exception.
|
||
*/
|
||
|
||
HRESULT GetCurrentException([out] ICorDebugValue **ppExceptionObject);
|
||
|
||
/*
|
||
* This is not implemented.
|
||
*/
|
||
|
||
HRESULT ClearCurrentException();
|
||
|
||
/*
|
||
* CreateStepper creates a stepper object which operates relative
|
||
* to the active frame in the given thread. (Note that this may be
|
||
* unmanaged code.) The Stepper API must then be used to perform
|
||
* actual stepping.
|
||
*
|
||
*/
|
||
|
||
HRESULT CreateStepper([out] ICorDebugStepper **ppStepper);
|
||
|
||
/*
|
||
* EnumerateChains returns an enum which will return all the stack
|
||
* chains in the thread, starting at the active (most recent) one.
|
||
* These chains represent the physical call stack for the thread.
|
||
*
|
||
* Chain boundaries occur for several reasons:
|
||
* managed <-> unmanaged transitions
|
||
* context switches
|
||
* debugger hijacking of user threads
|
||
*
|
||
* Note that in the simple case for a thread running purely
|
||
* managed code in a single context there will be a one to one
|
||
* correspondence between threads & chains.
|
||
*
|
||
* A debugger may want to rearrange the physical call
|
||
* stacks of all threads into logical call stacks. This would involve
|
||
* sorting all the threads' chains by their caller/callee
|
||
* relationships & regrouping them.
|
||
*
|
||
*/
|
||
|
||
HRESULT EnumerateChains([out] ICorDebugChainEnum **ppChains);
|
||
|
||
/*
|
||
* GetActiveChain is a convenience routine to return the
|
||
* active (most recent) chain on the thread, if any.
|
||
*
|
||
*/
|
||
|
||
HRESULT GetActiveChain([out] ICorDebugChain **ppChain);
|
||
|
||
/*
|
||
* GetActiveFrame is a convenience routine to return the
|
||
* active (most recent) frame on the thread, if any.
|
||
* If there are no frames on the stack, ppFrame will point to NULL
|
||
* and the function still returns S_OK.
|
||
*/
|
||
|
||
HRESULT GetActiveFrame([out] ICorDebugFrame **ppFrame);
|
||
|
||
/*
|
||
* GetRegisterSet returns the register set for the active part
|
||
* of the thread.
|
||
*
|
||
*/
|
||
|
||
HRESULT GetRegisterSet([out] ICorDebugRegisterSet **ppRegisters);
|
||
|
||
/*
|
||
* CreateEval creates an evaluation object which operates on the
|
||
* given thread. The Eval will push a new chain on the thread before
|
||
* doing its computation.
|
||
*
|
||
* Note that this interrupts the computation currently
|
||
* being performed on the thread until the eval completes.
|
||
*
|
||
*/
|
||
|
||
HRESULT CreateEval([out] ICorDebugEval **ppEval);
|
||
|
||
/*
|
||
* Returns the runtime thread object.
|
||
*/
|
||
|
||
HRESULT GetObject([out] ICorDebugValue **ppObject);
|
||
|
||
};
|
||
|
||
/*
|
||
* ICorDebugThread2 is a logical extension to ICorDebugThread.
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(2BD956D9-7B07-4bef-8A98-12AA862417C5),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugThread2 : IUnknown
|
||
{
|
||
|
||
typedef struct _COR_ACTIVE_FUNCTION
|
||
{
|
||
ICorDebugAppDomain *pAppDomain; // Pointer to the owning AppDomain of the below IL Offset.
|
||
ICorDebugModule *pModule; // Pointer to the owning Module of the below IL Offset.
|
||
ICorDebugFunction2 *pFunction; // Pointer to the owning Function of the below IL Offset.
|
||
ULONG32 ilOffset; // IL Offset of the frame.
|
||
ULONG32 flags; // Bit mask of flags, currently unused. Reserved.
|
||
} COR_ACTIVE_FUNCTION;
|
||
|
||
/*
|
||
* Retrieves the active functions for the given threads' frames. This
|
||
* includes AppDomain ID, Module ID, Funtion ID and IL offset for
|
||
* each active statement on the stack. A flags field is also included
|
||
* for future information about the frame that might need to be conveyed.
|
||
*
|
||
* If pFunctions is NULL, returns only the number of functions that
|
||
* is on the stack in pcFunctions.
|
||
*/
|
||
|
||
HRESULT GetActiveFunctions([in] ULONG32 cFunctions,
|
||
[out] ULONG32 *pcFunctions,
|
||
[in, out, size_is(cFunctions), length_is(*pcFunctions)]
|
||
COR_ACTIVE_FUNCTION pFunctions[]
|
||
);
|
||
/*
|
||
* Returns 0 if not part of a connection
|
||
* Maps to a SPID in SQL Server
|
||
*/
|
||
HRESULT GetConnectionID(
|
||
[out] CONNID *pdwConnectionId);
|
||
|
||
/*
|
||
* Return the TASKID of this thread.
|
||
*/
|
||
HRESULT GetTaskID(
|
||
[out] TASKID *pTaskId);
|
||
|
||
/*
|
||
* Return the OS Thread ID
|
||
*/
|
||
HRESULT GetVolatileOSThreadID(
|
||
[out] DWORD *pdwTid);
|
||
|
||
/*
|
||
* Allow the debugger to intercept the current exception on a thread. It can be
|
||
* called between an Exception callback and the associated call to ICorDebugProcess::Continue.
|
||
*
|
||
* pFrame specifies where we should intercept the exception. It must be a valid ICDFrame pointer,
|
||
* which can be obtained from a stackwalk. However, you must not call Continue() between
|
||
* doing the stackwalk and calling this function.
|
||
*/
|
||
HRESULT InterceptCurrentException(
|
||
[in] ICorDebugFrame *pFrame);
|
||
}
|
||
|
||
|
||
|
||
/*
|
||
* ICorDebugThread3 is a logical extension to ICorDebugThread.
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(F8544EC3-5E4E-46c7-8D3E-A52B8405B1F5),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugThread3 : IUnknown
|
||
{
|
||
HRESULT CreateStackWalk([out] ICorDebugStackWalk **ppStackWalk);
|
||
|
||
HRESULT GetActiveInternalFrames([in] ULONG32 cInternalFrames,
|
||
[out] ULONG32 *pcInternalFrames,
|
||
[in, out, size_is(cInternalFrames), length_is(*pcInternalFrames)]
|
||
ICorDebugInternalFrame2 * ppInternalFrames[]
|
||
);
|
||
};
|
||
|
||
/*
|
||
* ICorDebugThread4 is a logical extension to ICorDebugThread.
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(1A1F204B-1C66-4637-823F-3EE6C744A69C),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugThread4 : IUnknown
|
||
{
|
||
/*
|
||
* Returns S_OK if ICorDebugThread::GetCurrentException() is non-NULL and the exception
|
||
* it refers to has completed the first pass of exception handling without locating
|
||
* a catch clause.
|
||
* Returns S_FALSE if there is no exception, it hasn't completed first pass handling,
|
||
* or a catch handler was located
|
||
* Returns an appropriate error HRESULT when the answer can not be determined
|
||
*/
|
||
HRESULT HasUnhandledException();
|
||
|
||
HRESULT GetBlockingObjects([out] ICorDebugBlockingObjectEnum **ppBlockingObjectEnum);
|
||
/*
|
||
* Gets the current CustomNotification object on the current thread. This could be NULL if no
|
||
* current notification object exists. If we aren't currently inside a CustomNotification callback,
|
||
* this will always return NULL.
|
||
* A debugger can examine this object to determine how to handle the notification.
|
||
* See ICorDebugManagedCallback3::CustomNotification for more information about
|
||
* custom notifications.
|
||
*/
|
||
HRESULT GetCurrentCustomDebuggerNotification([out] ICorDebugValue ** ppNotificationObject);
|
||
};
|
||
|
||
/*
|
||
* The new V3.0 stackwalking API.
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(A0647DE9-55DE-4816-929C-385271C64CF7),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugStackWalk : IUnknown
|
||
{
|
||
typedef enum CorDebugSetContextFlag
|
||
{
|
||
SET_CONTEXT_FLAG_ACTIVE_FRAME = 0x1,
|
||
SET_CONTEXT_FLAG_UNWIND_FRAME = 0x2,
|
||
} CorDebugSetContextFlag;
|
||
|
||
/*
|
||
* Get the current context of this stack frame.
|
||
*
|
||
* The CONTEXT is retrieved from the ICorDebugStackWalk. As unwinding may only restore a subset of the
|
||
* registers, such as only non-volatile registers, the context may not exactly match the register state at
|
||
* the time of the actual call.
|
||
*/
|
||
HRESULT GetContext([in] ULONG32 contextFlags,
|
||
[in] ULONG32 contextBufSize,
|
||
[out] ULONG32* contextSize,
|
||
[out, size_is(contextBufSize)] BYTE contextBuf[]);
|
||
|
||
/*
|
||
* Change the current context of this stack walk, allowing the
|
||
* debugger to move it to an arbitrary context. Does not actually
|
||
* alter the current context of the thread whose stack is being walked.
|
||
*
|
||
* The CONTEXT has to be a valid CONTEXT of a stack frame on the thread.
|
||
* If the CONTEXT is outside of the current thread's stack range, we'll
|
||
* return a failure HRESULT. Otherwise, in the case of an invalid CONTEXT,
|
||
* the result is undefined.
|
||
*/
|
||
HRESULT SetContext([in] CorDebugSetContextFlag flag,
|
||
[in] ULONG32 contextSize,
|
||
[in, size_is(contextSize)] BYTE context[]);
|
||
|
||
/*
|
||
* Attempt to advance the stackwalk to the next frame.
|
||
* If the current frame type is a native stack frame, Next() will not advance to the caller frame.
|
||
* Instead, Next() will advance to the next managed stack frame or the next internal frame marker.
|
||
*
|
||
* If a debugger wants to unwind unmanaged stack frames, it needs to start from the
|
||
* native stack frame itself. It can seed the unwind by calling GetContext().
|
||
*
|
||
* This function will return CORDBG_S_AT_END_OF_STACK when there are no more frames.
|
||
*/
|
||
HRESULT Next();
|
||
|
||
/*
|
||
* Return the current frame. If the stackwalker is stopped at a native stack frame, we will return S_FALSE
|
||
* and set pFrame to NULL.
|
||
*/
|
||
HRESULT GetFrame([out] ICorDebugFrame ** pFrame);
|
||
};
|
||
|
||
|
||
/*
|
||
* ICorDebugChain represents a segment of a physical or logical call
|
||
* stack. All frames in a chain occupy contiguous stack space, and
|
||
* they share the same thread & context. A chain may represent either
|
||
* managed or unmanaged code. Chains may be empty. Unmanaged chains are
|
||
* always empty.
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCAEE-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugChain : IUnknown
|
||
{
|
||
/*
|
||
* GetThread returns the physical thread which this call chain is
|
||
* part of.
|
||
*/
|
||
|
||
HRESULT GetThread([out] ICorDebugThread **ppThread);
|
||
|
||
/*
|
||
* GetStackRange returns the address range of the stack segment for the
|
||
* call chain. Note that you cannot make any assumptions about
|
||
* what is actually stored on the stack - the numeric range is to compare
|
||
* stack frame locations only.
|
||
* The start of a stack range is the leafmost boundary of the chain, and
|
||
* the end of a stack range is the rootmost boundary of the chain.
|
||
*/
|
||
|
||
HRESULT GetStackRange([out] CORDB_ADDRESS *pStart, [out] CORDB_ADDRESS *pEnd);
|
||
|
||
/*
|
||
* NOT YET IMPLEMENTED
|
||
*/
|
||
|
||
HRESULT GetContext([out] ICorDebugContext **ppContext);
|
||
|
||
/*
|
||
* GetCaller returns a pointer to the chain which called this
|
||
* chain. Note that this may be a chain on another thread in the
|
||
* case of cross-thread-marshalled calls. The caller will be NULL
|
||
* for spontaneously called chains (e.g. the ThreadProc, a
|
||
* debugger initiated call, etc.)
|
||
*/
|
||
|
||
HRESULT GetCaller([out] ICorDebugChain **ppChain);
|
||
|
||
/*
|
||
* GetCallee returns a pointer to the chain which this chain is
|
||
* waiting on before it resumes. Note that this may be a chain on
|
||
* another thread in the case of cross-thread-marshalled
|
||
* calls. The callee will be NULL if the chain is currently
|
||
* actively running.
|
||
*/
|
||
|
||
HRESULT GetCallee([out] ICorDebugChain **ppChain);
|
||
|
||
/*
|
||
* GetPrevious returns a pointer to the chain which was on this
|
||
* thread before the current one was pushed, if there is one.
|
||
*/
|
||
|
||
HRESULT GetPrevious([out] ICorDebugChain **ppChain);
|
||
|
||
/*
|
||
* GetNext returns a pointer to the chain which was pushed on this
|
||
* thread after the current one, if there is one.
|
||
*/
|
||
|
||
HRESULT GetNext([out] ICorDebugChain **ppChain);
|
||
|
||
/*
|
||
* IsManaged returns whether or not the chain is running managed
|
||
* code.
|
||
*/
|
||
|
||
HRESULT IsManaged([out] BOOL *pManaged);
|
||
|
||
/*
|
||
* These chains represent the physical call stack for the thread.
|
||
* EnumerateFrames returns an iterator which will list all the stack
|
||
* frames in the chain, starting at the active (most recent) one. This
|
||
* should be called only for managed chains.
|
||
*
|
||
* NOTE: The debugging API does not provide methods for obtaining
|
||
* frames contained in unmanaged chains. The debugger needs to use
|
||
* other means to obtain this information.
|
||
*/
|
||
|
||
HRESULT EnumerateFrames([out] ICorDebugFrameEnum **ppFrames);
|
||
|
||
/*
|
||
* GetActiveFrame is a convenience routine to return the
|
||
* active (most recent) frame on the chain, if any.
|
||
*
|
||
* If the active frame is not available, the call will succeed
|
||
* and *ppFrame will be NULL. Active frames will not be available
|
||
* for all CHAIN_ENTER_UNMANAGED chains, and for some
|
||
* CHAIN_CLASS_INIT chains.
|
||
*/
|
||
|
||
HRESULT GetActiveFrame([out] ICorDebugFrame **ppFrame);
|
||
|
||
/*
|
||
* GetRegisterSet returns the register set for the beginnning (the leafmost end)
|
||
* of the chain.
|
||
*/
|
||
|
||
HRESULT GetRegisterSet([out] ICorDebugRegisterSet **ppRegisters);
|
||
|
||
/*
|
||
* GetReason returns the reason for the genesis of this calling chain.
|
||
*/
|
||
|
||
typedef enum CorDebugChainReason
|
||
{
|
||
// Note that the first five line up with CorDebugIntercept
|
||
CHAIN_NONE = 0x000,
|
||
CHAIN_CLASS_INIT = 0x001,
|
||
CHAIN_EXCEPTION_FILTER = 0x002,
|
||
CHAIN_SECURITY = 0x004,
|
||
CHAIN_CONTEXT_POLICY = 0x008,
|
||
CHAIN_INTERCEPTION = 0x010,
|
||
CHAIN_PROCESS_START = 0x020,
|
||
CHAIN_THREAD_START = 0x040,
|
||
CHAIN_ENTER_MANAGED = 0x080,
|
||
CHAIN_ENTER_UNMANAGED = 0x100,
|
||
CHAIN_DEBUGGER_EVAL = 0x200,
|
||
CHAIN_CONTEXT_SWITCH = 0x400,
|
||
CHAIN_FUNC_EVAL = 0x800,
|
||
} CorDebugChainReason;
|
||
|
||
HRESULT GetReason([out] CorDebugChainReason *pReason);
|
||
};
|
||
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCAEF-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugFrame : IUnknown
|
||
{
|
||
/*
|
||
* GetChain returns the chain of which this stack frame is a part.
|
||
*/
|
||
|
||
HRESULT GetChain([out] ICorDebugChain **ppChain);
|
||
|
||
/*
|
||
* GetCode returns the code which this stack frame is running if any.
|
||
*/
|
||
|
||
HRESULT GetCode([out] ICorDebugCode **ppCode);
|
||
|
||
/*
|
||
* GetFunction returns the function for the code which this stack
|
||
* frame is running.
|
||
* For ICorDebugInternalFrames, this may point to a method the
|
||
* frame is associated with (which may be in a different AppDomain
|
||
* from the frame itself), or may fail if the frame doesn't relate to any
|
||
* particular function.
|
||
*/
|
||
|
||
HRESULT GetFunction([out] ICorDebugFunction **ppFunction);
|
||
|
||
/*
|
||
* GetFunctionToken is a convenience routine to return the token for the
|
||
* function for the code which this stack frame is running.
|
||
* The scope to resolve the token can be gotten from the ICorDebugFunction
|
||
* associated with this frame.
|
||
*/
|
||
|
||
HRESULT GetFunctionToken([out] mdMethodDef *pToken);
|
||
|
||
/*
|
||
* GetStackRange returns the absolute address range of the stack
|
||
* frame. (This is useful for piecing together interleaved stack
|
||
* traces gathered from multiple debugging engines.) Note that you
|
||
* cannot make any assumptions about what is actually stored on
|
||
* the stack - the numeric range is to compare stack frame
|
||
* locations only.
|
||
* The start of a stack range is the leafmost boundary of the frame, and
|
||
* the end of a stack range is the rootmost boundary of the frame.
|
||
*/
|
||
|
||
HRESULT GetStackRange([out] CORDB_ADDRESS *pStart, [out] CORDB_ADDRESS *pEnd);
|
||
|
||
/*
|
||
* GetCaller returns a pointer to the frame in the current chain
|
||
* which called this frame, or NULL if this is the rootmost frame
|
||
* in the chain.
|
||
*/
|
||
|
||
HRESULT GetCaller([out] ICorDebugFrame **ppFrame);
|
||
|
||
/*
|
||
* GetCallee returns a pointer to the frame in the current chain
|
||
* which this frame called, or NULL if this is the leafmost frame
|
||
* in the chain.
|
||
*/
|
||
|
||
HRESULT GetCallee([out] ICorDebugFrame **ppFrame);
|
||
|
||
/*
|
||
* CreateStepper creates a stepper object which operates relative to the
|
||
* frame. The Stepper API must then be used to perform actual stepping.
|
||
*
|
||
* Note that if this frame is not active, the frame will typically have to
|
||
* be returned to before the step is completed.
|
||
*
|
||
*/
|
||
|
||
HRESULT CreateStepper([out] ICorDebugStepper **ppStepper);
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(B92CC7F7-9D2D-45c4-BC2B-621FCC9DFBF4),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugInternalFrame : ICorDebugFrame
|
||
{
|
||
|
||
typedef enum CorDebugInternalFrameType
|
||
{
|
||
// This is a 'null' value for GetFrameType and is included for completeness sake.
|
||
// ICorDebugInternalFrame::GetFrameType() should never actually return this.
|
||
STUBFRAME_NONE = 0x00000000,
|
||
|
||
// This frame is a M2U stub-frame. This could include both PInvoke
|
||
// and COM-interop calls.
|
||
STUBFRAME_M2U = 0x0000001,
|
||
|
||
// This is a U2M stub frame.
|
||
STUBFRAME_U2M = 0x0000002,
|
||
|
||
// AppDomain transition.
|
||
STUBFRAME_APPDOMAIN_TRANSITION = 0x00000003,
|
||
|
||
// LightWeight method calls.
|
||
STUBFRAME_LIGHTWEIGHT_FUNCTION = 0x00000004,
|
||
|
||
// Start of Func-eval. This is included for CHF callbacks.
|
||
// Funcevals also have a chain CHAIN_FUNC_EVAL (legacy from v1.0)
|
||
STUBFRAME_FUNC_EVAL = 0x00000005,
|
||
|
||
// Start of an internal call into the CLR.
|
||
STUBFRAME_INTERNALCALL = 0x00000006,
|
||
|
||
// start of a class initialization; corresponds to CHAIN_CLASS_INIT
|
||
STUBFRAME_CLASS_INIT = 0x00000007,
|
||
|
||
// an exception is thrown; corresponds to CHAIN_EXCEPTION_FILTER
|
||
STUBFRAME_EXCEPTION = 0x00000008,
|
||
|
||
// a frame used for code-access security purposes; corresponds to CHAIN_SECURITY
|
||
STUBFRAME_SECURITY = 0x00000009,
|
||
|
||
// a frame used to mark that the runtime is jitting a managed method
|
||
STUBFRAME_JIT_COMPILATION = 0x0000000a,
|
||
} CorDebugInternalFrameType;
|
||
|
||
// Get the type of internal frame. This will never be STUBFRAME_NONE.
|
||
// Debuggers should gracefully ignore unrecognized internal frame types.
|
||
HRESULT GetFrameType([out] CorDebugInternalFrameType * pType);
|
||
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(C0815BDC-CFAB-447e-A779-C116B454EB5B),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugInternalFrame2 : IUnknown
|
||
{
|
||
/*
|
||
* Returns the stack address of the internal frame marker.
|
||
*/
|
||
HRESULT GetAddress([out] CORDB_ADDRESS *pAddress);
|
||
|
||
/*
|
||
* Check if an internal frame is closer to the leaf than pFrameToCompare.
|
||
*/
|
||
HRESULT IsCloserToLeaf([in] ICorDebugFrame * pFrameToCompare,
|
||
[out] BOOL * pIsCloser);
|
||
};
|
||
|
||
/*
|
||
* ICorDebugILFrame is a specialized interface of ICorDebugFrame for IL frames or jitted frames.
|
||
* (Note that jitted frames implement both ICorDebugILFrame and ICorDebugNativeFrame.)
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(03E26311-4F76-11d3-88C6-006097945418),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugILFrame : ICorDebugFrame
|
||
{
|
||
/*
|
||
* GetIP returns the stack frame's offset into the function's IL code.
|
||
* If this stack frame is active, this address is the next
|
||
* instruction to execute. If this stack frame is not active, this is the
|
||
* next instruction to execute when the stack frame is reactivated.
|
||
*
|
||
* Note that if this a jitted frame, the IP will be determined by
|
||
* mapping backwards from the actual native IP, so the value may
|
||
* be only approximately correct.
|
||
*
|
||
* If pMappingResult is not NULL, A mapping result is returned which
|
||
* indicates the details of how the IP was obtained. The following values
|
||
* can be returned:
|
||
*
|
||
* MAPPING_EXACT - the IP is correct; either the frame is
|
||
* interpreted or there is an exact IL map for the function.
|
||
*
|
||
* MAPPING_APPROXIMATE - the IP was successfully mapped, but may
|
||
* be only approximately correct
|
||
*
|
||
* MAPPING_UNMAPPED_ADDRESS - although there is mapping info for
|
||
* the function, the current address is not mappable to IL. An
|
||
* IP of 0 is returned.
|
||
*
|
||
* MAPPING_PROLOG - the native code is in the prolog, so an IP of
|
||
* 0 is returned
|
||
*
|
||
* MAPPING_EPILOG - the native code is in an epilog, so the last
|
||
* IP of the method is returned
|
||
*
|
||
* MAPPING_NO_INFO - no mapping info is available for the method,
|
||
* so an IP of 0 is returned
|
||
*
|
||
*/
|
||
|
||
typedef enum CorDebugMappingResult
|
||
{
|
||
MAPPING_PROLOG = 0x1,
|
||
MAPPING_EPILOG = 0x2,
|
||
MAPPING_NO_INFO = 0x4,
|
||
MAPPING_UNMAPPED_ADDRESS = 0x8,
|
||
MAPPING_EXACT = 0x10,
|
||
MAPPING_APPROXIMATE = 0x20,
|
||
} CorDebugMappingResult;
|
||
|
||
HRESULT GetIP([out] ULONG32 *pnOffset, [out] CorDebugMappingResult *pMappingResult);
|
||
|
||
/*
|
||
* SetIP sets the instruction pointer to the IL at the given offset.
|
||
* The debugger will do its best to fix up the state of the executing code
|
||
* so that it is consistent with the new IP as far as the EE is concerned,
|
||
* while preserving as much of the state of the user program as possible.
|
||
*
|
||
* Calling SetIP immediately invalidates all frames and chains for the
|
||
* current thread; the debugger must perform a new stack trace if it
|
||
* requires frame information after calling SetIP.
|
||
*
|
||
*/
|
||
|
||
HRESULT SetIP([in] ULONG32 nOffset);
|
||
|
||
/*
|
||
* EnumerateLocalVariables returns a list of the local variables
|
||
* available in the frame. Note that this may not include all of
|
||
* the locals in the running function, as some of them may not be
|
||
* active.
|
||
*/
|
||
|
||
HRESULT EnumerateLocalVariables([out] ICorDebugValueEnum **ppValueEnum);
|
||
|
||
/*
|
||
* GetLocalVariable gets the value for a local variable
|
||
* in an IL frame. This can be used either in an IL
|
||
* frame or a jitted frame.
|
||
*/
|
||
|
||
HRESULT GetLocalVariable([in] DWORD dwIndex,
|
||
[out] ICorDebugValue **ppValue);
|
||
|
||
/*
|
||
* EnumerateArguments returns a list of the arguments available in the
|
||
* frame. Note that this will include varargs arguments as well as
|
||
* arguments declared by the function signature (inlucding the implicit
|
||
* "this" argument if any).
|
||
*/
|
||
|
||
HRESULT EnumerateArguments([out] ICorDebugValueEnum **ppValueEnum);
|
||
|
||
/*
|
||
* GetArgument gets the value for an argument
|
||
* in an IL frame. This can be used either in an IL
|
||
* frame or a jitted frame.
|
||
* For instance (non-static) methods, argument index 0 is the "this" object,
|
||
* and the normal explicit arguments start with index 1.
|
||
*/
|
||
|
||
HRESULT GetArgument([in] DWORD dwIndex,
|
||
[out] ICorDebugValue **ppValue);
|
||
|
||
/*
|
||
* NOT YET IMPLEMENTED
|
||
*/
|
||
|
||
HRESULT GetStackDepth([out] ULONG32 *pDepth);
|
||
|
||
/*
|
||
* NOT YET IMPLEMENTED
|
||
*/
|
||
|
||
HRESULT GetStackValue([in] DWORD dwIndex,
|
||
[out] ICorDebugValue **ppValue);
|
||
|
||
/*
|
||
* CanSetIP attempts to determine if it's safe to set the instruction pointer
|
||
* to the IL at the given offset. If this returns S_OK, then executing
|
||
* SetIP (see above) will result in a safe, correct, continued execution.
|
||
* If CanSetIP returns anything else, SetIP can still be invoked, but
|
||
* continued, correct execution of the debuggee cannot be guaranteed.
|
||
*
|
||
*/
|
||
|
||
HRESULT CanSetIP([in] ULONG32 nOffset);
|
||
};
|
||
|
||
|
||
/*
|
||
* ICorDebugILFrame2 is a logical extension to ICorDebugILFrame.
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(5D88A994-6C30-479b-890F-BCEF88B129A5),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugILFrame2 : IUnknown
|
||
{
|
||
/*
|
||
* Performs an on-stack replacement for an outstanding function remap opportunity.
|
||
* This is used to update execution of an edited function to the latest version,
|
||
* preserving the current frame state (such as the values of all locals).
|
||
* This can only be called when a FunctionRemapOpportunity callback has been delivered
|
||
* for this leaf frame, and the callback has not yet been continued. newILOffset
|
||
* is the offset into the new function at which execution should continue.
|
||
* When the remap has completed, a FunctionRemapComplete callback will be delivered.
|
||
*/
|
||
HRESULT RemapFunction([in] ULONG32 newILOffset);
|
||
|
||
/*
|
||
* EnumerateTypeParameters returns the type parameters active on a frame.
|
||
* This will include both the class type parameters (if any) followed by the method type
|
||
* parameters (if any).
|
||
* Use the metadata API IMetaDataImport2::EnumGenericParams to determine how many
|
||
* Class type parameters vs. Method Type parameters there are in this list.
|
||
* The type parameters will not always be available.
|
||
*/
|
||
|
||
HRESULT EnumerateTypeParameters([out] ICorDebugTypeEnum **ppTyParEnum);
|
||
|
||
};
|
||
|
||
/*
|
||
* ICorDebugNativeFrame is a specialized interface of ICorDebugFrame for jitted frames, i.e.
|
||
* native frames for managed methods.
|
||
* (Note that jitted frames implement both ICorDebugILFrame and ICorDebugNativeFrame.)
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(03E26314-4F76-11d3-88C6-006097945418),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugNativeFrame : ICorDebugFrame
|
||
{
|
||
/*
|
||
* GetIP returns the stack frame's offset into the function's
|
||
* native code. If this stack frame is active, this address is
|
||
* the next instruction to execute. If this stack frame is not
|
||
* active, this is the next instruction to execute when the stack
|
||
* frame is reactivated.
|
||
*/
|
||
|
||
HRESULT GetIP([out] ULONG32 *pnOffset);
|
||
|
||
/*
|
||
* SetIP sets the instruction pointer to the given native
|
||
* offset. CorDebug will attempt to keep the stack frame in a
|
||
* coherent state. (Note that even if the frame is in a valid
|
||
* state as far as the runtime is concerned, there still may be
|
||
* problems - e.g. uninitialized local variables, etc. The caller
|
||
* (or perhaps the user) is responsible for insuring coherency of
|
||
* the running program.)
|
||
*
|
||
* Calling SetIP immediately invalidates all frames and chains for the
|
||
* current thread; the debugger must perform a new stack trace if it
|
||
* requires frame information after calling SetIP.
|
||
*/
|
||
|
||
HRESULT SetIP([in] ULONG32 nOffset);
|
||
|
||
/*
|
||
* GetRegisterSet returns the register set for the given frame.
|
||
*
|
||
*/
|
||
|
||
HRESULT GetRegisterSet([out] ICorDebugRegisterSet **ppRegisters);
|
||
|
||
/*
|
||
* GetLocalRegisterValue gets the value for a local variable or
|
||
* argument stored in a register of a native frame. This can be
|
||
* used either in a native frame or a jitted frame.
|
||
*/
|
||
|
||
HRESULT GetLocalRegisterValue([in] CorDebugRegister reg,
|
||
[in] ULONG cbSigBlob,
|
||
[in] PCCOR_SIGNATURE pvSigBlob,
|
||
[out] ICorDebugValue **ppValue);
|
||
|
||
/*
|
||
* GetLocalDoubleRegisterValue gets the value for a local variable
|
||
* or argument stored in 2 registers of a native frame. This can
|
||
* be used either in a native frame or a jitted frame.
|
||
*/
|
||
|
||
HRESULT GetLocalDoubleRegisterValue([in] CorDebugRegister highWordReg,
|
||
[in] CorDebugRegister lowWordReg,
|
||
[in] ULONG cbSigBlob,
|
||
[in] PCCOR_SIGNATURE pvSigBlob,
|
||
[out] ICorDebugValue **ppValue);
|
||
|
||
/*
|
||
* GetLocalMemoryValue gets the value for a local variable stored
|
||
* at the given address.
|
||
*/
|
||
|
||
HRESULT GetLocalMemoryValue([in] CORDB_ADDRESS address,
|
||
[in] ULONG cbSigBlob,
|
||
[in] PCCOR_SIGNATURE pvSigBlob,
|
||
[out] ICorDebugValue **ppValue);
|
||
|
||
/*
|
||
* GetLocalRegisterMemoryValue gets the value for a local which
|
||
* is stored half in a register and half in memory.
|
||
*/
|
||
|
||
HRESULT GetLocalRegisterMemoryValue([in] CorDebugRegister highWordReg,
|
||
[in] CORDB_ADDRESS lowWordAddress,
|
||
[in] ULONG cbSigBlob,
|
||
[in] PCCOR_SIGNATURE pvSigBlob,
|
||
[out] ICorDebugValue **ppValue);
|
||
|
||
/*
|
||
* GetLocalMemoryRegisterValue gets the value for a local which
|
||
* is stored half in a register and half in memory.
|
||
*/
|
||
|
||
HRESULT GetLocalMemoryRegisterValue([in] CORDB_ADDRESS highWordAddress,
|
||
[in] CorDebugRegister lowWordRegister,
|
||
[in] ULONG cbSigBlob,
|
||
[in] PCCOR_SIGNATURE pvSigBlob,
|
||
[out] ICorDebugValue **ppValue);
|
||
/*
|
||
* CanSetIP attempts to determine if it's safe to set the instruction pointer
|
||
* to the given native offset. If this returns S_OK, then executing
|
||
* SetIP (see above) will result in a safe, correct, continued execution.
|
||
* If CanSetIP returns anything else, SetIP can still be invoked, but
|
||
* continued, correct execution of the debuggee cannot be guaranteed.
|
||
*
|
||
*/
|
||
|
||
HRESULT CanSetIP([in] ULONG32 nOffset);
|
||
};
|
||
|
||
#pragma warning(push)
|
||
#pragma warning(disable:28718) /* suppress warning 28718 for interface ICorDebugModule */
|
||
[
|
||
object,
|
||
local,
|
||
uuid(35389FF1-3684-4c55-A2EE-210F26C60E5E),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugNativeFrame2 : IUnknown
|
||
{
|
||
/*
|
||
* Returns true if the current frame is a child frame.
|
||
*/
|
||
HRESULT IsChild([out] BOOL *pIsChild);
|
||
|
||
/*
|
||
* Return true if the specified frame is the parent frame of the current frame.
|
||
*/
|
||
HRESULT IsMatchingParentFrame([in] ICorDebugNativeFrame2 *pPotentialParentFrame,
|
||
[out] BOOL *pIsParent);
|
||
|
||
/*
|
||
* Return the stack parameter size on x86. On other platforms, we return S_FALSE and set pSize to 0.
|
||
* This is because other platforms don't need this information for unwinding.
|
||
*/
|
||
HRESULT GetStackParameterSize([out] ULONG32 * pSize);
|
||
};
|
||
|
||
/*
|
||
* ICorDebugModule3 is a logical extension to ICorDebugModule.
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(86F012BF-FF15-4372-BD30-B6F11CAAE1DD),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugModule3 : IUnknown
|
||
{
|
||
/*
|
||
* CreateReaderForInMemorySymbols creates a debug symbol reader object (eg.
|
||
* ISymUnmanagedReader) for a dynamic module. This symbol reader becomes stale
|
||
* and is usually discarded whenever a LoadClass callback is delivered for the
|
||
* module.
|
||
*
|
||
* Arguments:
|
||
* riid - The IID of the COM interface to return (typically IID_ISymUnmanagedReader)
|
||
* ppObj - Where to store the reader interface.
|
||
*
|
||
* Return Value:
|
||
* S_OK on success
|
||
* Error hresults otherwise, including:
|
||
* CORDBG_E_MODULE_LOADED_FROM_DISK if this isn't an in-memory or dynamic module
|
||
* CORDBG_E_SYMBOLS_NOT_AVAILABLE if symbols weren't supplied by the application or aren't
|
||
* yet available.
|
||
*
|
||
* Notes:
|
||
* This API can also be used to create a symbol reader object for in-memory
|
||
* (non-dynamic) modules, but only after the symbols are first available
|
||
* (indicated by the UpdateModuleSymbols callback).
|
||
*
|
||
* This API returns a new reader instance every time it is called (like CoCreateInstance)
|
||
* and so the debugger should cache the result and only request a new one when
|
||
* the underlying data may have changed (i.e. a LoadClass event).
|
||
*
|
||
* Dynamic modules do not have any symbols available until the first type has been
|
||
* loaded into them (as indicated by the LoadClass callback).
|
||
*/
|
||
HRESULT CreateReaderForInMemorySymbols([in] REFIID riid,
|
||
[out][iid_is(riid)] void **ppObj);
|
||
}
|
||
|
||
/*
|
||
* ICorDebugRuntimeUnwindableFrame is a specialized interface of ICorDebugFrame for unmanaged methods
|
||
* which requires special knowledge to unwind. They are not jitted code. When the debugger sees this type
|
||
* of frames, it should use ICorDebugStackWalk::Next() to unwind, but it should do inspection itself.
|
||
* The debugger can call ICorDebugStackWalk::GetContext() to retrieve the CONTEXT of the frame when it gets
|
||
* an ICorDebugRuntimeUnwindableFrame.
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(879CAC0A-4A53-4668-B8E3-CB8473CB187F),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugRuntimeUnwindableFrame : ICorDebugFrame
|
||
{
|
||
}
|
||
|
||
/*
|
||
* ICorDebugModule represents a Common Language Runtime module that is loaded into a
|
||
* specific AppDomain. Normally this is an executable or a DLL, but it may also be
|
||
* some other file of a multi-module assembly. There is an ICorDebugModule instance
|
||
* for each AppDomain a module is loaded into, even in the case of shared modules like
|
||
* mscorlib.
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(dba2d8c1-e5c5-4069-8c13-10a7c6abf43d),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugModule : IUnknown
|
||
{
|
||
/*
|
||
* GetProcess returns the process of which this module is a part.
|
||
*/
|
||
|
||
HRESULT GetProcess([out] ICorDebugProcess **ppProcess);
|
||
|
||
/*
|
||
* GetBaseAddress returns the base address of the module.
|
||
*
|
||
* For modules loaded from NGEN images, the base address will be 0.
|
||
*/
|
||
|
||
HRESULT GetBaseAddress([out] CORDB_ADDRESS *pAddress);
|
||
|
||
/*
|
||
* GetAssembly returns the assembly of which this module is a part.
|
||
*/
|
||
|
||
HRESULT GetAssembly([out] ICorDebugAssembly **ppAssembly);
|
||
|
||
/*
|
||
* GetName returns a name identifying the module.
|
||
*
|
||
* For on-disk modules this is a full path. For dynamic modules this
|
||
* is just the filename if one was provided. Otherwise, and for other
|
||
* in-memory modules, this is just the simple name stored in the module's
|
||
* metadata.
|
||
*/
|
||
|
||
HRESULT GetName([in] ULONG32 cchName,
|
||
[out] ULONG32 *pcchName,
|
||
[out, size_is(cchName),
|
||
length_is(*pcchName)] WCHAR szName[]);
|
||
|
||
/*
|
||
* EnableJITDebugging controls whether the jitter preserves
|
||
* debugging information for methods within this module.
|
||
* If bTrackJITInfo is true, then the jitter preserves
|
||
* mapping information between the IL version of a function and
|
||
* the jitted version for functions in the module. If bAllowJitOpts
|
||
* is true, then the jitter will generate code with certain (JIT-specific)
|
||
* optimizations.
|
||
*
|
||
* JITDebug is enabled by default for all modules loaded when the
|
||
* debugger is active. Programmatically enabling/disabling these
|
||
* settings will override global settings.
|
||
*
|
||
*/
|
||
HRESULT EnableJITDebugging([in] BOOL bTrackJITInfo,
|
||
[in] BOOL bAllowJitOpts);
|
||
|
||
/*
|
||
* EnableClassLoadCallbacks controls whether on not LoadClass and
|
||
* UnloadClass callbacks are called for the particular module.
|
||
* For non-dynamic modules, they are off by default.
|
||
* For dynamic modules, they are on by default and can not be disabled.
|
||
*/
|
||
|
||
HRESULT EnableClassLoadCallbacks([in] BOOL bClassLoadCallbacks);
|
||
|
||
/*
|
||
* GetFunctionFromToken returns the ICorDebugFunction from
|
||
* metadata information. Returns CORDBG_E_FUNCTION_NOT_IL if
|
||
* called with a methodDef that does not refer to an IL method.
|
||
* In the EnC case, this will return the most recent version of the function.
|
||
*/
|
||
|
||
HRESULT GetFunctionFromToken([in] mdMethodDef methodDef,
|
||
[out] ICorDebugFunction **ppFunction);
|
||
|
||
/*
|
||
* NOT YET IMPLEMENTED
|
||
*/
|
||
|
||
HRESULT GetFunctionFromRVA([in] CORDB_ADDRESS rva,
|
||
[out] ICorDebugFunction **ppFunction);
|
||
|
||
/*
|
||
* GetClassFromToken returns the ICorDebugClass from metadata information.
|
||
*/
|
||
|
||
HRESULT GetClassFromToken([in] mdTypeDef typeDef,
|
||
[out] ICorDebugClass **ppClass);
|
||
|
||
/*
|
||
* NOT YET IMPLEMENTED
|
||
*/
|
||
|
||
HRESULT CreateBreakpoint([out] ICorDebugModuleBreakpoint **ppBreakpoint);
|
||
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
|
||
HRESULT GetEditAndContinueSnapshot([out] ICorDebugEditAndContinueSnapshot **ppEditAndContinueSnapshot);
|
||
|
||
/*
|
||
* Return a metadata interface pointer that can be used to examine the
|
||
* metadata for this module.
|
||
*/
|
||
HRESULT GetMetaDataInterface([in] REFIID riid, [out] IUnknown **ppObj);
|
||
|
||
|
||
/*
|
||
* Return the token for the Module table entry for this object. The token
|
||
* may then be passed to the meta data import api's.
|
||
*/
|
||
HRESULT GetToken([out] mdModule *pToken);
|
||
|
||
/*
|
||
* If this is a dynamic module, IsDynamic sets *pDynamic to true, otherwise
|
||
* sets *pDynamic to false.
|
||
* Dynamic modules can continue to grow new classes (receive LoadClass callbacks) even after
|
||
* the module is loaded.
|
||
*/
|
||
HRESULT IsDynamic([out] BOOL *pDynamic);
|
||
|
||
/*
|
||
* GetGlobalVariableValue returns a value object for the given global
|
||
* variable.
|
||
*/
|
||
HRESULT GetGlobalVariableValue([in] mdFieldDef fieldDef,
|
||
[out] ICorDebugValue **ppValue);
|
||
|
||
/*
|
||
* GetSize returns the size, in bytes, of the module.
|
||
*
|
||
* For modules loaded from NGEN images, the size will be 0.
|
||
*/
|
||
HRESULT GetSize([out] ULONG32 *pcBytes);
|
||
|
||
/*
|
||
* If this is a module that exists only in the debuggee's memory,
|
||
* then pInMemory will be set to TRUE. The Runtime supports
|
||
* loading assemblies from raw streams of bytes. Such modules are
|
||
* called "in memory" modules and they have no on-disk
|
||
* representation.
|
||
*/
|
||
HRESULT IsInMemory([out] BOOL *pInMemory);
|
||
};
|
||
#pragma warning(pop)
|
||
|
||
/*
|
||
* ICorDebugModule2 is a logical extension to ICorDebugModule.
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(7FCC5FB5-49C0-41de-9938-3B88B5B9ADD7),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugModule2 : IUnknown
|
||
{
|
||
/*
|
||
* SetUserCode sets the user-code status of all the functions on all the classes in
|
||
* the module to bIsJustMyCode, except for the functions or classes in the tokens array,
|
||
* which it sets to !bIsJustMyCode.
|
||
* These settings erase all previous JMC settings in this module.
|
||
* JMC status can be refined by calls to SetJMCStatus on the Class and Function.
|
||
* Returns S_OK if all functions were set successfully,
|
||
* CORDBG_E_FUNCTION_NOT_DEBUGGABLE if some function to be marked TRUE was not
|
||
* debuggable.
|
||
*/
|
||
HRESULT SetJMCStatus([in] BOOL bIsJustMyCode,
|
||
[in] ULONG32 cTokens,
|
||
[in, size_is(cTokens)] mdToken pTokens[]);
|
||
|
||
/*
|
||
* ApplyChanges is called to apply an Edit and Continue delta to the running process.
|
||
* An EnC delta consists of a delta metadata blob (created by IMetadataEmit2::SaveDelta)
|
||
* and a delta IL blob (a method body stream just like the one in an on disk assembly).
|
||
* If this operation fails, the debug session is considered to be in an invalid state
|
||
* and must be restarted.
|
||
*/
|
||
HRESULT ApplyChanges([in] ULONG cbMetadata,
|
||
[in, size_is(cbMetadata)] BYTE pbMetadata[],
|
||
[in] ULONG cbIL,
|
||
[in, size_is(cbIL)] BYTE pbIL[]);
|
||
|
||
/*
|
||
* SetJITCompilerFlags sets the flags that control the JIT compiler. If the set of flags is invalid,
|
||
* the function will fail. This function can only be called from within the true LoadModule callback
|
||
* for the given module. Attempts to call it after this callback has been delivered or in a "faked"
|
||
* LoadModule callback for debugger attach will fail.
|
||
*/
|
||
|
||
HRESULT SetJITCompilerFlags( [in] DWORD dwFlags );
|
||
|
||
/*
|
||
* GetJITCompilerFlags gets the set of flags that control the JIT compiler for this module.
|
||
*/
|
||
|
||
HRESULT GetJITCompilerFlags( [out] DWORD *pdwFlags );
|
||
|
||
/*
|
||
* Resolve an assembly given an AssemblyRef token. Note that
|
||
* this will not trigger the loading of assembly. If assembly is not yet loaded,
|
||
* this will return an CORDBG_E_CANNOT_RESOLVE_ASSEMBLY error
|
||
*
|
||
*/
|
||
HRESULT ResolveAssembly([in] mdToken tkAssemblyRef,
|
||
[out] ICorDebugAssembly **ppAssembly);
|
||
|
||
};
|
||
|
||
|
||
/*
|
||
ICorDebugFunction represents a managed function.
|
||
In the non-EnC case, it is 1:1 with a methoddef metadata token.
|
||
For EnC, each version of a function has its own ICorDebugFunction instance.
|
||
EnCed functions keep the same metadata tokens, but will get new ICorDebugCode instances.
|
||
|
||
ICorDebugFunction does not represent generic typeparameters. That means that there's
|
||
an ICDFunction for Func<T>, but not for Func<string> or Func<Bar>. Get the generic
|
||
parameters from ICorDebugIlFrame::EnumerateTypeParameters.
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCAF3-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugFunction : IUnknown
|
||
{
|
||
/*
|
||
* GetModule returns the module for the function.
|
||
*/
|
||
|
||
HRESULT GetModule([out] ICorDebugModule **ppModule);
|
||
|
||
/*
|
||
* GetClass returns the class for the function. Returns null if
|
||
* the function is not a member.
|
||
*/
|
||
|
||
HRESULT GetClass([out] ICorDebugClass **ppClass);
|
||
|
||
/*
|
||
* GetToken returns the metadata methodDef token for the function.
|
||
*/
|
||
|
||
HRESULT GetToken([out] mdMethodDef *pMethodDef);
|
||
|
||
/*
|
||
* GetILCode returns the IL code for the function. Returns null
|
||
* if there is no IL code for the function. Note that this will
|
||
* get the IL code corresponding to this function's EnC version of
|
||
* the code in the runtime, if this function has been EnC'd.
|
||
*/
|
||
|
||
HRESULT GetILCode([out] ICorDebugCode **ppCode);
|
||
|
||
/*
|
||
* GetNativeCode returns the native code for the function.
|
||
* Returns null if there is no native code for the function
|
||
* (i.e. it is an IL function which has not been jitted)
|
||
* If this function has been jitted multiple times (Eg, generics) this
|
||
* will return a random Native Code object.
|
||
*/
|
||
|
||
HRESULT GetNativeCode([out] ICorDebugCode **ppCode);
|
||
|
||
/*
|
||
* CreateBreakpoint creates a breakpoint at the start of the function.
|
||
*
|
||
*/
|
||
|
||
HRESULT CreateBreakpoint([out] ICorDebugFunctionBreakpoint **ppBreakpoint);
|
||
|
||
/*
|
||
* Returns the token for the local variable signature for this function.
|
||
* If there is no signature (ie, the function doesn't have any local
|
||
* variables), then mdSignatureNil will be returned.
|
||
*/
|
||
|
||
HRESULT GetLocalVarSigToken([out] mdSignature *pmdSig);
|
||
|
||
|
||
/*
|
||
* Obtains the latest (largest) EnC version number for this function.
|
||
* If this function has never been edited with EnC, this will return
|
||
* the same value as ICorDebugFunction2::GetVersionNumber.
|
||
*/
|
||
HRESULT GetCurrentVersionNumber([out] ULONG32 *pnCurrentVersion);
|
||
};
|
||
|
||
/*
|
||
ICorDebugFunction2 is a logical extension to ICorDebugFunction.
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(EF0C490B-94C3-4e4d-B629-DDC134C532D8),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugFunction2 : IUnknown
|
||
{
|
||
/*
|
||
* Sets the User-code status (for JMC stepping) for this function.
|
||
* A JMC stepper will skip non-user code.
|
||
* User code must be a subset of debuggable code.
|
||
* Returns S_OK if successful, CORDBG_E_FUNCTION_NOT_DEBUGGABLE
|
||
* if bIsJustMyCode is TRUE and the function is not debuggable.
|
||
*/
|
||
HRESULT SetJMCStatus([in] BOOL bIsJustMyCode);
|
||
|
||
/*
|
||
* IsUserCode outputs whether the function is marked as user code.
|
||
* Always outputs FALSE for non-debuggable functions.
|
||
* Returns S_OK if successful.
|
||
*/
|
||
HRESULT GetJMCStatus([out] BOOL * pbIsJustMyCode);
|
||
|
||
/*
|
||
* Not yet implemented.
|
||
*/
|
||
|
||
HRESULT EnumerateNativeCode([out] ICorDebugCodeEnum **ppCodeEnum);
|
||
|
||
/*
|
||
* Obtains the EnC version number of the function represented by this ICorDebugFunction2.
|
||
* When a function is edited with EnC, the new function has a larger version number than
|
||
* that of any previous version (not necessarily exactly 1 greater).
|
||
* This function's version number will be less than or equal to the value returned by
|
||
* ICorDebugFunction::GetCurrentVersionNumber.
|
||
*/
|
||
|
||
HRESULT GetVersionNumber([out] ULONG32 *pnVersion);
|
||
};
|
||
|
||
/*
|
||
ICorDebugCode represents an IL or native code blob.
|
||
|
||
For methods that take offsets, the units are the same as the units on the CordbCode object.
|
||
(eg, IL offsets for an IL code object, and native offsets for a native code object)
|
||
|
||
V2 allows multiple code-regions. CordbCode presents an abstraction where these
|
||
are merged together in a single linear, continuous space. So if the code is split
|
||
with 0x5 bytes at address 0x1000, and 0x10 bytes at address 0x2000,
|
||
then:
|
||
- GetAddress() yields a start address of 0x1000.
|
||
- GetSize() is the size of the merged regions = 0x5+ 0x10 = 0x15 bytes.
|
||
- The (Offset --> Address) mapping is:
|
||
0x0 --> 0x1000
|
||
0x1 --> 0x1001
|
||
0x4 --> 0x1004
|
||
0x5 --> 0x2000
|
||
0x6 --> 0x2001
|
||
0x15 --> 0x2010
|
||
|
||
A caller can get the specific code regions via ICorDebugCode2.
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCAF4-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugCode : IUnknown
|
||
{
|
||
/*
|
||
* IsIL returns whether the code is IL (as opposed to native.)
|
||
*/
|
||
|
||
HRESULT IsIL([out] BOOL *pbIL);
|
||
|
||
/*
|
||
* GetFunction returns the function for the code.
|
||
*/
|
||
|
||
HRESULT GetFunction([out] ICorDebugFunction **ppFunction);
|
||
|
||
/*
|
||
* GetAddress returns the address of the code.
|
||
*/
|
||
|
||
HRESULT GetAddress([out] CORDB_ADDRESS *pStart);
|
||
|
||
/*
|
||
* GetSize returns the size in bytes of the code.
|
||
*/
|
||
|
||
HRESULT GetSize([out] ULONG32 *pcBytes);
|
||
|
||
/*
|
||
* CreateBreakpoint creates a breakpoint in the function at the
|
||
* given offset.
|
||
*
|
||
* If this code is IL code, and there is a jitted native version
|
||
* of the code, the breakpoint will be applied in the jitted code
|
||
* as well. (The same is true if the code is later jitted.)
|
||
*
|
||
*/
|
||
|
||
HRESULT CreateBreakpoint([in] ULONG32 offset,
|
||
[out] ICorDebugFunctionBreakpoint **ppBreakpoint);
|
||
|
||
/*
|
||
* GetCode returns the code of the method, suitable for disassembly. Note
|
||
* that instruction boundaries aren't checked.
|
||
* This glues together multiple code-regions into a single binary stream.
|
||
* Caller must use ICorDebugCode2::GetCodeChunks to get (start,size) for
|
||
* code chunks to be able to properly resolve addresses embedded in the instructions.
|
||
*/
|
||
|
||
HRESULT GetCode([in] ULONG32 startOffset, [in] ULONG32 endOffset,
|
||
[in] ULONG32 cBufferAlloc,
|
||
[out, size_is(cBufferAlloc),
|
||
length_is(*pcBufferSize)] BYTE buffer[],
|
||
[out] ULONG32 *pcBufferSize);
|
||
|
||
/*
|
||
* GetVersionNumber returns the 1 based number identifying the
|
||
* version of the code that this ICorDebugCode corresponds to. The
|
||
* version number is incremented each time the function is Edit-And-
|
||
* Continue'd.
|
||
*/
|
||
|
||
HRESULT GetVersionNumber([out] ULONG32 *nVersion);
|
||
|
||
/*
|
||
* GetILToNativeMapping returns a map from IL offsets to native
|
||
* offsets for this code. An array of COR_DEBUG_IL_TO_NATIVE_MAP
|
||
* structs will be returned, and some of the ilOffsets in this array
|
||
* map be the values specified in CorDebugIlToNativeMappingTypes.
|
||
*
|
||
* Note: this method is only valid for ICorDebugCodes representing
|
||
* native code that was jitted from IL code.
|
||
* Note: There is no ordering to the array of elements returned, nor
|
||
* should you assume that there is or will be.
|
||
*/
|
||
HRESULT GetILToNativeMapping([in] ULONG32 cMap,
|
||
[out] ULONG32 *pcMap,
|
||
[out, size_is(cMap), length_is(*pcMap)]
|
||
COR_DEBUG_IL_TO_NATIVE_MAP map[]);
|
||
|
||
/*
|
||
* Not implemented.
|
||
*/
|
||
HRESULT GetEnCRemapSequencePoints([in] ULONG32 cMap,
|
||
[out] ULONG32 *pcMap,
|
||
[out, size_is(cMap), length_is(*pcMap)]
|
||
ULONG32 offsets[]);
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(5F696509-452F-4436-A3FE-4D11FE7E2347),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugCode2 : IUnknown
|
||
{
|
||
typedef struct _CodeChunkInfo
|
||
{
|
||
CORDB_ADDRESS startAddr;
|
||
ULONG32 length;
|
||
} CodeChunkInfo;
|
||
|
||
// The native code for a code object may be split up into multiple regions.
|
||
//
|
||
HRESULT GetCodeChunks(
|
||
[in] ULONG32 cbufSize,
|
||
[out] ULONG32 * pcnumChunks,
|
||
[out, size_is(cbufSize), length_is(*pcnumChunks)] CodeChunkInfo chunks[]);
|
||
|
||
|
||
// GetCompilerFlags returns the flags under which this piece of code was JITted or NGENed.
|
||
|
||
HRESULT GetCompilerFlags( [out] DWORD *pdwFlags );
|
||
};
|
||
|
||
|
||
/*
|
||
ICorDebugClass represents a Class (mdTypeDef) in the IL image.
|
||
For generic types, it represents the generic type definition (eg. List<T>) not any of
|
||
the specific instantiations (eg. List<int>).
|
||
|
||
Use ICorDebugClass2::GetParameterizedType to build an ICorDebugType from an
|
||
ICorDebugClass and type parameters.
|
||
|
||
Classes live in a module and are uniquely identified by a mdTypeDef.
|
||
In other words, you can round-trip a class like so:
|
||
ICorDebugClass * pClass1 = ...; // some initial class
|
||
|
||
ICorDebugModule * pModule = NULL;
|
||
pClass1->GetModule(&pModule);
|
||
|
||
mdTypeDef token;
|
||
pClass1->GetToken(&token);
|
||
|
||
ICorDebugClass * pClass2;
|
||
pModule->GetClassFromToken(token, &pClass2);
|
||
// Now: pClass1 == pClass2
|
||
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCAF5-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugClass : IUnknown
|
||
{
|
||
/*
|
||
* GetModule returns the module for the class.
|
||
*/
|
||
|
||
HRESULT GetModule([out] ICorDebugModule **pModule);
|
||
|
||
/*
|
||
* GetTypeDefToken returns the metadata typedef token for the class.
|
||
*/
|
||
|
||
HRESULT GetToken([out] mdTypeDef *pTypeDef);
|
||
|
||
/*
|
||
* GetStaticFieldValue returns a value object (ICorDebugValue) for the given static field
|
||
* variable. If the static field could possibly be relative to either
|
||
* a thread, context, or appdomain, then pFrame will help the debugger
|
||
* determine the proper value.
|
||
*
|
||
* Note that if the class accepts type parameters, then you should
|
||
* use GetStaticField on an appropriate ICorDebugType rather than on the
|
||
* ICorDebugClass.
|
||
*
|
||
* Returns:
|
||
* S_OK on success.
|
||
* CORDBG_E_FIELD_NOT_STATIC if the field is not static.
|
||
* CORDBG_E_STATIC_VAR_NOT_AVAILABLE if field is not yet available (storage for statics
|
||
* may be lazily allocated).
|
||
* CORDBG_E_VARIABLE_IS_ACTUALLY_LITERAL if the field is actually a metadata literal. In this
|
||
* case, the debugger should get the value from the metadata.
|
||
* error on other errors.
|
||
*/
|
||
|
||
HRESULT GetStaticFieldValue([in] mdFieldDef fieldDef,
|
||
[in] ICorDebugFrame *pFrame,
|
||
[out] ICorDebugValue **ppValue);
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(B008EA8D-7AB1-43f7-BB20-FBB5A04038AE),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugClass2 : IUnknown
|
||
{
|
||
/*
|
||
* GetParameterizedType returns a type that corresponds to this class.
|
||
*
|
||
* If the class is non-generic, i.e. has no type parameters, then
|
||
* this simply gets the type object corresponding to the class.
|
||
* elementType should be set to the correct element type for the
|
||
* class, i.e. ELEMENT_TYPE_VALUETYPE if the class is a value type
|
||
* otherwise ELEMENT_TYPE_CLASS.
|
||
*
|
||
* If the class accepts type parameters, e.g. ArrayList<T>, then
|
||
* this function can be used to construct a type object for an
|
||
* instantiated type such as ArrayList<int>.
|
||
*/
|
||
HRESULT GetParameterizedType([in] CorElementType elementType,
|
||
[in] ULONG32 nTypeArgs,
|
||
[in, size_is(nTypeArgs)] ICorDebugType *ppTypeArgs[],
|
||
[out] ICorDebugType **ppType);
|
||
|
||
/*
|
||
* Sets the User-code status (for JMC stepping) for all methods
|
||
* in this class. This is functionally equivalent to setting the
|
||
* JMCStatus onall methods in this class.
|
||
* A JMC stepper will skip non-user code.
|
||
* User code must be a subset of debuggable code.
|
||
*
|
||
* Returns S_OK if all methods are set succesfully.
|
||
* Return failure if any are not set.
|
||
* On failure, some may still be set.
|
||
*/
|
||
HRESULT SetJMCStatus([in] BOOL bIsJustMyCode);
|
||
|
||
};
|
||
|
||
/* ------------------------------------------------------------------------- *
|
||
* Function call interfaces
|
||
* ------------------------------------------------------------------------- */
|
||
|
||
/*
|
||
* ICorDebugEval collects functionality which requires running code
|
||
* inside the debuggee. Note that the operations do not complete until
|
||
* ICorDebugProcess::Continue is called, and the EvalComplete callback
|
||
* is called.
|
||
*
|
||
* An ICorDebugEval object is created in the context of a specific
|
||
* thread, which will be used to perform the evaluations.
|
||
*
|
||
* If you need to use this functionality without allowing other threads
|
||
* to run, set the DebugState of the program's threads to STOP
|
||
* before calling Continue.
|
||
*
|
||
* Note that since user code is running when the evaluation is in
|
||
* progress, any debug events can occur, including class loads,
|
||
* breakpoints, etc. Callbacks will be called normally in such a
|
||
* case. The state of the Eval will be seen as part of the normal
|
||
* program state inspection, the stack chain will be a CHAIN_FUNC_EVAL chain;
|
||
* the full debugger API continues to operate as normal. Evals can even be nested.
|
||
*
|
||
* Also, the user code may never complete due to deadlock or infinite
|
||
* looping. In this case you will need to Abort the Eval before
|
||
* resuming the program.
|
||
*
|
||
* All objects and types used in a given func-eval must all reside within the
|
||
* same app domain. That app-domain need not be the same as the current
|
||
* app domain of the thread.
|
||
*
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCAF6-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugEval : IUnknown
|
||
{
|
||
/*
|
||
* CallFunction sets up a function call. Note that if the function
|
||
* is virtual, this will perform virtual dispatch. If the function is
|
||
* not static, then the first argument must be the "this" object.
|
||
* If the function is in an a different AppDomain, a transition will
|
||
* occur (but all arguments must also be in the target AppDomain)
|
||
*/
|
||
|
||
HRESULT CallFunction([in] ICorDebugFunction *pFunction,
|
||
[in] ULONG32 nArgs,
|
||
[in, size_is(nArgs)] ICorDebugValue *ppArgs[]);
|
||
|
||
/*
|
||
* NewObject allocates and calls the constructor for an object.
|
||
*/
|
||
|
||
HRESULT NewObject([in] ICorDebugFunction *pConstructor,
|
||
[in] ULONG32 nArgs,
|
||
[in, size_is(nArgs)] ICorDebugValue *ppArgs[]);
|
||
|
||
/*
|
||
* NewObjectNoConstructor allocates a new object without
|
||
* attempting to call any constructor on the object.
|
||
*/
|
||
|
||
HRESULT NewObjectNoConstructor([in] ICorDebugClass *pClass);
|
||
|
||
/*
|
||
* NewString allocates a string object with the given contents.
|
||
* The string is always created in the AppDomain the thread is currently in.
|
||
*/
|
||
|
||
HRESULT NewString([in] LPCWSTR string);
|
||
|
||
/*
|
||
* NewArray allocates a new array with the given element type and
|
||
* dimensions. If the elementType is a primitive, pElementClass
|
||
* may be NULL. Otherwise, pElementClass should be the class of
|
||
* the elements of the array. Note: lowBounds is optional. If
|
||
* omitted, a zero lower bound for each dimension is assumed.
|
||
* The array is always created in the AppDomain the thread is currently in.
|
||
*
|
||
* NOTE: In the current release, rank must be 1.
|
||
*/
|
||
|
||
HRESULT NewArray([in] CorElementType elementType,
|
||
[in] ICorDebugClass *pElementClass,
|
||
[in] ULONG32 rank,
|
||
[in, size_is(rank)] ULONG32 dims[],
|
||
[in, size_is(rank)] ULONG32 lowBounds[]);
|
||
|
||
/*
|
||
* IsActive returns whether the func-eval is currently executing.
|
||
*/
|
||
|
||
HRESULT IsActive([out] BOOL *pbActive);
|
||
|
||
/*
|
||
* Abort aborts the current computation. Note that in the case of nested
|
||
* Evals, this may fail unless it is the most recent Eval.
|
||
*/
|
||
|
||
HRESULT Abort();
|
||
|
||
/*
|
||
* GetResult returns the result of the evaluation. This is only
|
||
* valid after the evaluation is completed.
|
||
*
|
||
* If the evaluation completes normally, the result will be the
|
||
* return value. If it terminates with an exception, the result
|
||
* is the exception thrown. If the evaluation was for a new object,
|
||
* the return value is the reference to the object.
|
||
*/
|
||
|
||
HRESULT GetResult([out] ICorDebugValue **ppResult);
|
||
|
||
/*
|
||
* GetThread returns the thread on which this eval will run or is running.
|
||
*/
|
||
|
||
HRESULT GetThread([out] ICorDebugThread **ppThread);
|
||
|
||
/*
|
||
* CreateValue creates an ICorDebugValue of the given type for the
|
||
* sole purpose of using it in a function evaluation. These can be
|
||
* used to pass user constants as parameters. The value has a zero
|
||
* or NULL initial value. Use ICorDebugValue::SetValue to
|
||
* set the value.
|
||
*
|
||
* pElementClass is only required for value classes. Pass NULL
|
||
* otherwise.
|
||
*
|
||
* If elementType == ELEMENT_TYPE_CLASS, then you get an
|
||
* ICorDebugReferenceValue representing the NULL object reference.
|
||
* You can use this to pass NULL to evals that have object reference
|
||
* parameters. You cannot set the ICorDebugReferenceValue to
|
||
* anything... it always remains NULL.
|
||
*/
|
||
|
||
HRESULT CreateValue([in] CorElementType elementType,
|
||
[in] ICorDebugClass *pElementClass,
|
||
[out] ICorDebugValue **ppValue);
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(FB0D9CE7-BE66-4683-9D32-A42A04E2FD91),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugEval2 : IUnknown
|
||
{
|
||
/*
|
||
* CallParameterizedFunction is like CallFunction except the function
|
||
* may be inside a class with type parameters, or may itself take type
|
||
* parameters, or both. The type arguments should be given for the
|
||
* class first, then the function.
|
||
*
|
||
* If the function is in an a different AppDomain, a transition will occur.
|
||
* However, all type and value arguments must be in the target AppDomain.
|
||
*
|
||
* Func-eval can only be performed in limited scenarios. If Call*Function
|
||
* fails, then the HR makes a best effort at describing the most general
|
||
* possible reason for failure.
|
||
*/
|
||
|
||
HRESULT CallParameterizedFunction([in] ICorDebugFunction *pFunction,
|
||
[in] ULONG32 nTypeArgs,
|
||
[in, size_is(nTypeArgs)] ICorDebugType *ppTypeArgs[],
|
||
[in] ULONG32 nArgs,
|
||
[in, size_is(nArgs)] ICorDebugValue *ppArgs[]);
|
||
|
||
/*
|
||
* CreateValueForType generalizes CreateValue by allowing you to specify an
|
||
* arbitrary object type including constructed types such as List<int>.
|
||
* Once again the sole purpose is to generate a value to pass for a function evaluation.
|
||
*
|
||
* The element type of the type must be ELEMENT_TYPE_CLASS or
|
||
* ELEMENT_TYPE_VALUE, or one of the simple types. You cannot use this
|
||
* to create array values or string values.
|
||
*/
|
||
|
||
HRESULT CreateValueForType([in] ICorDebugType *pType,
|
||
[out] ICorDebugValue **ppValue);
|
||
|
||
/*
|
||
* NewParameterizedObject allocates and calls the constructor for an object.
|
||
* The object may be in a class that includes type parameters.
|
||
*/
|
||
|
||
HRESULT NewParameterizedObject([in] ICorDebugFunction *pConstructor,
|
||
[in] ULONG32 nTypeArgs,
|
||
[in, size_is(nTypeArgs)] ICorDebugType *ppTypeArgs[],
|
||
[in] ULONG32 nArgs,
|
||
[in, size_is(nArgs)] ICorDebugValue *ppArgs[]);
|
||
|
||
/*
|
||
* NewParameterizedObjectNoConstructor allocates a new object without
|
||
* attempting to call any constructor on the object.
|
||
* The object may be in a class that includes type parameters.
|
||
*/
|
||
|
||
HRESULT NewParameterizedObjectNoConstructor([in] ICorDebugClass *pClass,
|
||
[in] ULONG32 nTypeArgs,
|
||
[in, size_is(nTypeArgs)] ICorDebugType *ppTypeArgs[]);
|
||
|
||
/*
|
||
* NewParamaterizedArray allocates a new array whose elements may be instances
|
||
* of a generic type. The array is always created in the AppDomain the thread is
|
||
* currently in.
|
||
*/
|
||
HRESULT NewParameterizedArray([in] ICorDebugType *pElementType,
|
||
[in] ULONG32 rank,
|
||
[in, size_is(rank)] ULONG32 dims[],
|
||
[in, size_is(rank)] ULONG32 lowBounds[]);
|
||
|
||
/*
|
||
* NewStringWithLength allocates a string object with the given contents.
|
||
* The length is specified in uiLength. This is used for user to pass in null
|
||
* embedded string. If the string's tailing null is expected to be in
|
||
* the managed string, client has to ensure the length including the tailing null.
|
||
*
|
||
* The string is always created in the AppDomain the thread is currently in.
|
||
*/
|
||
|
||
HRESULT NewStringWithLength([in] LPCWSTR string,
|
||
[in] UINT uiLength);
|
||
|
||
/*
|
||
* RudeAbort aborts the current computation. Any locks the aborted
|
||
* eval was holding are not released, and thus the debugging session
|
||
* is in an unsafe state.
|
||
*/
|
||
|
||
HRESULT RudeAbort(void);
|
||
|
||
};
|
||
|
||
|
||
/* ------------------------------------------------------------------------- *
|
||
* Runtime value interfaces
|
||
* ------------------------------------------------------------------------- */
|
||
|
||
/*
|
||
* ICorDebugValue represents a value in the remote process. Note that
|
||
* the values can be both Get and Set; they are "lvalues".
|
||
*
|
||
* In general, ownership of a value object is passed when it is returned. The
|
||
* recipient is responsible for removing a reference from the object when
|
||
* finished with it.
|
||
*
|
||
* Depending on where the value was retrieved from, the value may not remain
|
||
* valid after the process is resumed,
|
||
* so in general they shouldn't be held across continues.
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCAF7-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugValue : IUnknown
|
||
{
|
||
/*
|
||
* GetType returns the simple type of the value. If the object
|
||
* has a more complex runtime type, that type may be examined through the
|
||
* appropriate subclasses (e.g. ICorDebugObjectValue can get the class of
|
||
* an object.)
|
||
*/
|
||
|
||
HRESULT GetType([out] CorElementType *pType);
|
||
|
||
/*
|
||
* GetSize returns the size of the value in bytes. Note that for reference
|
||
* types this will be the size of the pointer rather than the size of
|
||
* the object.
|
||
*/
|
||
|
||
HRESULT GetSize([out] ULONG32 *pSize);
|
||
|
||
/*
|
||
* GetAddress returns the address of the value in the debugee
|
||
* process. This might be useful information for the debugger to
|
||
* show.
|
||
*
|
||
* If the value is unavailable, 0 is returned. This could happen if
|
||
* it is at least partly in registers or stored in a GC Handle.
|
||
*/
|
||
|
||
HRESULT GetAddress([out] CORDB_ADDRESS *pAddress);
|
||
|
||
/*
|
||
* NOT YET IMPLEMENTED
|
||
*/
|
||
|
||
HRESULT CreateBreakpoint([out] ICorDebugValueBreakpoint **ppBreakpoint);
|
||
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(5E0B54E7-D88A-4626-9420-A691E0A78B49),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugValue2 : IUnknown
|
||
{
|
||
/*
|
||
* GetExactType returns the runtime type of the object in the value.
|
||
*/
|
||
|
||
HRESULT GetExactType([out] ICorDebugType **ppType);
|
||
|
||
};
|
||
|
||
/*
|
||
* ICorDebugGenericValue is a subclass of ICorDebugValue which applies to
|
||
* all values, and can be used to get & set the value. It is a
|
||
* separate subinterface because it is non-remotable.
|
||
*
|
||
* Note that for reference types, the value is the reference rather than
|
||
* the contents.
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCAF8-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugGenericValue : ICorDebugValue
|
||
{
|
||
/*
|
||
* GetValue copies the value into the specified buffer. The buffer should
|
||
* be the appropriate size for the simple type.
|
||
*/
|
||
|
||
HRESULT GetValue([out] void *pTo);
|
||
|
||
/*
|
||
* SetValue copies a new value from the specified buffer. The buffer should
|
||
* be the approprirate size for the simple type.
|
||
*
|
||
*/
|
||
|
||
HRESULT SetValue([in] void *pFrom);
|
||
};
|
||
|
||
/* ISSUE: an remotable interface for each simple type
|
||
*
|
||
* It might be nice to have a subclass with a typesafe Get/Set for each simple
|
||
* type.
|
||
*/
|
||
|
||
/*
|
||
* ICorDebugReferenceValue is a subclass of ICorDebugValue which applies to
|
||
* a reference type.
|
||
* The runtime may Garbage Collect objects once the debuggee is continued. The GC may
|
||
* move objects around in memory.
|
||
*
|
||
* An ICorDebugReference will either cooperate with GCs such that its information is updated
|
||
* after the GC, or it will be implicitly neutered before the GC.
|
||
*
|
||
* The ICorDebugReferenceValue inteface may be implicitly neutered after the debuggee
|
||
* has been continued. The derived ICorDebugHandleValue is not neutered until explicitly
|
||
* released or exposed.
|
||
*
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCAF9-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugReferenceValue : ICorDebugValue
|
||
{
|
||
/*
|
||
* IsNull tests whether the reference is null.
|
||
*/
|
||
|
||
HRESULT IsNull([out] BOOL *pbNull);
|
||
|
||
/*
|
||
* GetValue returns the current address of the object referred to by this
|
||
* reference.
|
||
*/
|
||
|
||
HRESULT GetValue([out] CORDB_ADDRESS *pValue);
|
||
|
||
/*
|
||
* SetValue sets this reference to refer to a different address.
|
||
*/
|
||
|
||
HRESULT SetValue([in] CORDB_ADDRESS value);
|
||
|
||
/*
|
||
* Dereference returns a ICorDebugValue representing the value
|
||
* referenced. This is only valid while the interface has not yet been neutered.
|
||
*/
|
||
|
||
HRESULT Dereference([out] ICorDebugValue **ppValue);
|
||
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
|
||
HRESULT DereferenceStrong([out] ICorDebugValue **ppValue);
|
||
};
|
||
|
||
/*
|
||
* ICorDebugHeapValue is a subclass of ICorDebugValue which represents
|
||
* a garbage collected object
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCAFA-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugHeapValue : ICorDebugValue
|
||
{
|
||
/*
|
||
* DEPRECATED.
|
||
* All objects are only valid until Continue is called, at which time they are neutered.
|
||
*/
|
||
|
||
HRESULT IsValid([out] BOOL *pbValid);
|
||
|
||
/*
|
||
* NOT YET IMPLEMENTED
|
||
*/
|
||
|
||
HRESULT CreateRelocBreakpoint([out]
|
||
ICorDebugValueBreakpoint **ppBreakpoint);
|
||
|
||
};
|
||
|
||
/*
|
||
* ICorDebugHeapValue2
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(E3AC4D6C-9CB7-43e6-96CC-B21540E5083C),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugHeapValue2 : IUnknown
|
||
{
|
||
|
||
/*
|
||
* Creates a handle of the given type for this heap value.
|
||
*
|
||
*/
|
||
HRESULT CreateHandle([in] CorDebugHandleType type, [out] ICorDebugHandleValue ** ppHandle);
|
||
|
||
};
|
||
|
||
/*
|
||
* ICorDebugHeapValue3 - exposes the monitor lock properties of objects
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(A69ACAD8-2374-46e9-9FF8-B1F14120D296),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugHeapValue3 : IUnknown
|
||
{
|
||
|
||
/*
|
||
* Gets the owning thread for a monitor lock
|
||
*/
|
||
HRESULT GetThreadOwningMonitorLock([out] ICorDebugThread **ppThread, [out] DWORD *pAcquisitionCount);
|
||
|
||
/*
|
||
* Gets the list of threads waiting on a monitor event
|
||
*/
|
||
HRESULT GetMonitorEventWaitList([out] ICorDebugThreadEnum **ppThreadEnum);
|
||
};
|
||
|
||
/*
|
||
* ICorDebugObjectValue is a subclass of ICorDebugValue which applies to
|
||
* values which contain an object.
|
||
* An ICorDebugObjectValue becomes invalid after the debuggee is continued.
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(18AD3D6E-B7D2-11d2-BD04-0000F80849BD),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugObjectValue : ICorDebugValue
|
||
{
|
||
/*
|
||
* GetClass returns the runtime class of the object in the value.
|
||
*/
|
||
|
||
HRESULT GetClass([out] ICorDebugClass **ppClass);
|
||
|
||
/*
|
||
* GetFieldValue returns a value for the given field in the given
|
||
* class. The class must be on the class hierarchy of the object's
|
||
* class, and the field must be a field of that class.
|
||
*/
|
||
|
||
HRESULT GetFieldValue([in] ICorDebugClass *pClass,
|
||
[in] mdFieldDef fieldDef,
|
||
[out] ICorDebugValue **ppValue);
|
||
|
||
/*
|
||
* NOT YET IMPLEMENTED
|
||
*/
|
||
|
||
HRESULT GetVirtualMethod([in] mdMemberRef memberRef,
|
||
[out] ICorDebugFunction **ppFunction);
|
||
|
||
/*
|
||
* NOT YET IMPLEMENTED
|
||
*/
|
||
|
||
HRESULT GetContext([out] ICorDebugContext **ppContext);
|
||
|
||
/*
|
||
* IsValueClass returns true if the the class of this object is
|
||
* a value class.
|
||
*/
|
||
|
||
HRESULT IsValueClass([out] BOOL *pbIsValueClass);
|
||
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
|
||
HRESULT GetManagedCopy([out] IUnknown **ppObject);
|
||
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
|
||
HRESULT SetFromManagedCopy([in] IUnknown *pObject);
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(49E4A320-4A9B-4eca-B105-229FB7D5009F),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugObjectValue2 : IUnknown
|
||
{
|
||
/*
|
||
* GetVirtualMethodForType returns the most derived function
|
||
* for the given ref on this object.
|
||
*
|
||
* Note: not yet implemented.
|
||
*/
|
||
|
||
HRESULT GetVirtualMethodAndType([in] mdMemberRef memberRef,
|
||
[out] ICorDebugFunction **ppFunction,
|
||
[out] ICorDebugType **ppType);
|
||
};
|
||
|
||
/*
|
||
* ICorDebugBoxValue is a subclass of ICorDebugValue which
|
||
* represents a boxed value class object.
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCAFC-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugBoxValue : ICorDebugHeapValue
|
||
{
|
||
/*
|
||
* GetObject returns the value object which is in the box.
|
||
*/
|
||
|
||
HRESULT GetObject([out] ICorDebugObjectValue **ppObject);
|
||
};
|
||
|
||
#pragma warning(push)
|
||
#pragma warning(disable:28718) /* suppress warning 28718 for interface ICorDebugStringValue */
|
||
/*
|
||
* ICorDebugStringValue is a subclass of ICorDebugValue which
|
||
* applies to values which contain a string. This interface
|
||
* provides an easy way to get the string contents.
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCAFD-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugStringValue : ICorDebugHeapValue
|
||
{
|
||
/*
|
||
* GetLength returns the number of characters in the string.
|
||
*/
|
||
|
||
HRESULT GetLength([out] ULONG32 *pcchString);
|
||
|
||
/*
|
||
* GetString returns the contents of the string.
|
||
*/
|
||
|
||
HRESULT GetString([in] ULONG32 cchString,
|
||
[out] ULONG32 *pcchString,
|
||
[out, size_is(cchString),
|
||
length_is(*pcchString)] WCHAR szString[]);
|
||
};
|
||
#pragma warning(pop)
|
||
|
||
/*
|
||
* ICorDebugArrayValue is a subclass of ICorDebugValue which applies
|
||
* to values which contain an array. This interface supports both
|
||
* single and multidimension arrays.
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(0405B0DF-A660-11d2-BD02-0000F80849BD),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugArrayValue : ICorDebugHeapValue
|
||
{
|
||
/*
|
||
* GetElementType returns the simple type of the elements in the
|
||
* array.
|
||
*/
|
||
|
||
HRESULT GetElementType([out] CorElementType *pType);
|
||
|
||
/*
|
||
* GetRank returns the number of dimensions in the array.
|
||
*/
|
||
|
||
HRESULT GetRank([out] ULONG32 *pnRank);
|
||
|
||
/*
|
||
* GetCount returns the total number of elements in the array.
|
||
*/
|
||
|
||
HRESULT GetCount([out] ULONG32 *pnCount);
|
||
|
||
/*
|
||
* GetDimensions returns the dimensions of the array.
|
||
*/
|
||
|
||
HRESULT GetDimensions([in] ULONG32 cdim,
|
||
[out, size_is(cdim),
|
||
length_is(cdim)] ULONG32 dims[]);
|
||
|
||
/*
|
||
* HasBaseIndicies returns whether or not the array has base indicies.
|
||
* If the answer is no, then all dimensions have a base index of 0.
|
||
*/
|
||
|
||
HRESULT HasBaseIndicies([out] BOOL *pbHasBaseIndicies);
|
||
|
||
/*
|
||
* GetBaseIndicies returns the base index of each dimension in
|
||
* the array
|
||
*/
|
||
|
||
HRESULT GetBaseIndicies([in] ULONG32 cdim,
|
||
[out, size_is(cdim),
|
||
length_is(cdim)] ULONG32 indicies[]);
|
||
|
||
/*
|
||
* GetElement returns a value representing the given element in the array.
|
||
* The indices array must not be null.
|
||
*/
|
||
|
||
HRESULT GetElement([in] ULONG32 cdim,
|
||
[in, size_is(cdim),
|
||
length_is(cdim)] ULONG32 indices[],
|
||
[out] ICorDebugValue **ppValue);
|
||
/*
|
||
* GetElementAtPosition returns the element at the given position,
|
||
* treating the array as a zero-based, single-dimensional array.
|
||
*
|
||
* Multidimensional array layout follows the C++ style of array layout.
|
||
*/
|
||
|
||
HRESULT GetElementAtPosition([in] ULONG32 nPosition,
|
||
[out] ICorDebugValue **ppValue);
|
||
};
|
||
|
||
|
||
/*
|
||
* ICorDebugHandleValue represents a reference value that the debugger has
|
||
* explicitly created a GC handle to. It does not represent GC Handles in the debuggee process,
|
||
|
||
* A normal ICorDebugReference becomes neutered after the debuggee has been
|
||
* continued. A ICorDebugHandleValue will survive across continues and can be
|
||
* dereferenced until the client explcitly disposes the handle.
|
||
*
|
||
*
|
||
* ICorDebugHeapValu2::CreateHandle will create ICorDebugHandleValue
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(029596E8-276B-46a1-9821-732E96BBB00B),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugHandleValue : ICorDebugReferenceValue
|
||
{
|
||
/*
|
||
* returns the type of this handle.
|
||
*
|
||
*/
|
||
HRESULT GetHandleType([out] CorDebugHandleType *pType);
|
||
|
||
|
||
/*
|
||
* The final release of the interface will also dispose of the handle. This
|
||
* API provides the ability for client to early dispose the handle.
|
||
*
|
||
*/
|
||
HRESULT Dispose();
|
||
|
||
};
|
||
|
||
|
||
/*
|
||
* ICorDebugContext represents a context object.
|
||
*
|
||
* Interface TBD.
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCB00-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugContext : ICorDebugObjectValue
|
||
{
|
||
};
|
||
|
||
|
||
/* ------------------------------------------------------------------------- *
|
||
* Enum interfaces
|
||
* ------------------------------------------------------------------------- */
|
||
|
||
/*
|
||
* ICorDebugEnum is an abstract enumerator.
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCB01-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugEnum : IUnknown
|
||
{
|
||
/*
|
||
* Moves the current position forward the given number of
|
||
* elements.
|
||
*/
|
||
HRESULT Skip([in] ULONG celt);
|
||
|
||
/*
|
||
* Sets the position of the enumerator to the beginning of the
|
||
* enumeration.
|
||
*/
|
||
HRESULT Reset();
|
||
|
||
/*
|
||
* Creates another enumerator with the same current position
|
||
* as this one.
|
||
*/
|
||
HRESULT Clone([out] ICorDebugEnum **ppEnum);
|
||
|
||
/*
|
||
* Gets the number of elements in the enumeration
|
||
*/
|
||
HRESULT GetCount([out] ULONG *pcelt);
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCB02-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugObjectEnum : ICorDebugEnum
|
||
{
|
||
/*
|
||
* Gets the next "celt" number of objects in the enumeration.
|
||
* The actual number of objects retrieved is returned in "pceltFetched".
|
||
* Returns S_FALSE if the actual number of objects retrieved is smaller
|
||
* than the number of objects requested.
|
||
*/
|
||
HRESULT Next([in] ULONG celt,
|
||
[out, size_is(celt),
|
||
length_is(*pceltFetched)] CORDB_ADDRESS objects[],
|
||
[out] ULONG *pceltFetched);
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCB03-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
|
||
interface ICorDebugBreakpointEnum : ICorDebugEnum
|
||
{
|
||
/*
|
||
* Gets the next "celt" number of breakpoints in the enumeration.
|
||
* The actual number of breakpoints retrieved is returned in "pceltFetched".
|
||
* Returns S_FALSE if the actual number of breakpoints retrieved is smaller
|
||
* than the number of breakpoints requested.
|
||
*/
|
||
HRESULT Next([in] ULONG celt,
|
||
[out, size_is(celt), length_is(*pceltFetched)]
|
||
ICorDebugBreakpoint *breakpoints[],
|
||
[out] ULONG *pceltFetched);
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCB04-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
|
||
interface ICorDebugStepperEnum : ICorDebugEnum
|
||
{
|
||
/*
|
||
* Gets the next "celt" number of steppers in the enumeration.
|
||
* The actual number of steppers retrieved is returned in "pceltFetched".
|
||
* Returns S_FALSE if the actual number of steppers retrieved is smaller
|
||
* than the number of steppers requested.
|
||
*/
|
||
HRESULT Next([in] ULONG celt,
|
||
[out, size_is(celt), length_is(*pceltFetched)]
|
||
ICorDebugStepper *steppers[],
|
||
[out] ULONG *pceltFetched);
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCB05-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugProcessEnum : ICorDebugEnum
|
||
{
|
||
/*
|
||
* Gets the next "celt" number of processes in the enumeration.
|
||
* The actual number of processes retrieved is returned in "pceltFetched".
|
||
* Returns S_FALSE if the actual number of processes retrieved is smaller
|
||
* than the number of processes requested.
|
||
*/
|
||
HRESULT Next([in] ULONG celt,
|
||
[out, size_is(celt), length_is(*pceltFetched)]
|
||
ICorDebugProcess *processes[],
|
||
[out] ULONG *pceltFetched);
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCB06-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugThreadEnum : ICorDebugEnum
|
||
{
|
||
/*
|
||
* Gets the next "celt" number of threads in the enumeration.
|
||
* The actual number of threads retrieved is returned in "pceltFetched".
|
||
* Returns S_FALSE if the actual number of threads retrieved is smaller
|
||
* than the number of threads requested.
|
||
*/
|
||
HRESULT Next([in] ULONG celt,
|
||
[out, size_is(celt), length_is(*pceltFetched)]
|
||
ICorDebugThread *threads[],
|
||
[out] ULONG *pceltFetched);
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCB07-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugFrameEnum : ICorDebugEnum
|
||
{
|
||
/*
|
||
* Gets the next "celt" number of frames in the enumeration.
|
||
* The actual number of frames retrieved is returned in "pceltFetched".
|
||
* Returns S_FALSE if the actual number of frames retrieved is smaller
|
||
* than the number of frames requested.
|
||
*/
|
||
HRESULT Next([in] ULONG celt,
|
||
[out, size_is(celt), length_is(*pceltFetched)]
|
||
ICorDebugFrame *frames[],
|
||
[out] ULONG *pceltFetched);
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCB08-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugChainEnum : ICorDebugEnum
|
||
{
|
||
/*
|
||
* Gets the next "celt" number of chains in the enumeration.
|
||
* The actual number of chains retrieved is returned in "pceltFetched".
|
||
* Returns S_FALSE if the actual number of chains retrieved is smaller
|
||
* than the number of chains requested.
|
||
*/
|
||
HRESULT Next([in] ULONG celt,
|
||
[out, size_is(celt), length_is(*pceltFetched)]
|
||
ICorDebugChain *chains[],
|
||
[out] ULONG *pceltFetched);
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCB09-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugModuleEnum : ICorDebugEnum
|
||
{
|
||
/*
|
||
* Gets the next "celt" number of modules in the enumeration.
|
||
* The actual number of modules retrieved is returned in "pceltFetched".
|
||
* Returns S_FALSE if the actual number of modules retrieved is smaller
|
||
* than the number of modules requested.
|
||
*/
|
||
HRESULT Next([in] ULONG celt,
|
||
[out, size_is(celt), length_is(*pceltFetched)]
|
||
ICorDebugModule *modules[],
|
||
[out] ULONG *pceltFetched);
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC7BCB0A-8A68-11d2-983C-0000F808342D),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugValueEnum : ICorDebugEnum
|
||
{
|
||
/*
|
||
* Gets the next "celt" number of values in the enumeration.
|
||
* The actual number of values retrieved is returned in "pceltFetched".
|
||
* Returns S_FALSE if the actual number of values retrieved is smaller
|
||
* than the number of values requested.
|
||
*/
|
||
HRESULT Next([in] ULONG celt,
|
||
[out, size_is(celt), length_is(*pceltFetched)]
|
||
ICorDebugValue *values[],
|
||
[out] ULONG *pceltFetched);
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(55E96461-9645-45e4-A2FF-0367877ABCDE),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugCodeEnum : ICorDebugEnum
|
||
{
|
||
/*
|
||
* Gets the next "celt" number of code objects in the enumeration.
|
||
* The actual number of code objects retrieved is returned in "pceltFetched".
|
||
* Returns S_FALSE if the actual number of code objects retrieved is smaller
|
||
* than the number of code objects requested.
|
||
*/
|
||
HRESULT Next([in] ULONG celt,
|
||
[out, size_is(celt), length_is(*pceltFetched)]
|
||
ICorDebugCode *values[],
|
||
[out] ULONG *pceltFetched);
|
||
};
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(10F27499-9DF2-43ce-8333-A321D7C99CB4),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugTypeEnum : ICorDebugEnum
|
||
{
|
||
/*
|
||
* Gets the next "celt" number of types in the enumeration.
|
||
* The actual number of types retrieved is returned in "pceltFetched".
|
||
* Returns S_FALSE if the actual number of types retrieved is smaller
|
||
* than the number of types requested.
|
||
*/
|
||
HRESULT Next([in] ULONG celt,
|
||
[out, size_is(celt), length_is(*pceltFetched)]
|
||
ICorDebugType *values[],
|
||
[out] ULONG *pceltFetched);
|
||
};
|
||
|
||
|
||
|
||
/*
|
||
* ICorDebugType represents an instantiated type in the debugggee.
|
||
* Unlike ICorDebugClass, it can store type-parameter information and thus can
|
||
* represent instantiated generic types (Eg, List<int>)
|
||
* Use the metadata interfaces to get static (Compile-time) information about the type.
|
||
*
|
||
* A type (and all of its type parameters) lives in an single AppDomain and becomes
|
||
* invalid once the containing ICorDebugAppDomain is unloaded.
|
||
*
|
||
* Types may be lazily loaded, so if the debugger queries for a type that hasn't been
|
||
* loaded yet, it may be unavailable.
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(D613F0BB-ACE1-4c19-BD72-E4C08D5DA7F5),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugType : IUnknown
|
||
{
|
||
/*
|
||
* GetType gets the basic type of the generic parameter. This can be used to
|
||
* determine if it is necessary to call GetClass to find the full information for the
|
||
* generic type parameter.
|
||
*/
|
||
HRESULT GetType([out] CorElementType *ty);
|
||
|
||
/*
|
||
* GetClass is used if the CorElementType returned by GetType is ELEMENT_TYPE_CLASS,
|
||
* ELEMENT_TYPE_VALUETYPE. If the type is a constructed type, e.g. List<String>,
|
||
* then this will return the ICorDebugClass for the type constructor, i.e. "List<T>".
|
||
*
|
||
* GetClass should not be used if the element type is anything other than these two element
|
||
* types. In particular, it may not be used if the element type is ELEMENT_TYPE_STRING.
|
||
*/
|
||
HRESULT GetClass([out] ICorDebugClass **ppClass);
|
||
|
||
/*
|
||
* EnumerateTypeParameters may be used if the CorElementType
|
||
* returned by GetType is one of ELEMENT_TYPE_CLASS,
|
||
* ELEMENT_TYPE_VALUETYPE, ELEMENT_TYPE_ARRAY, ELEMENT_TYPE_SZARRAY,
|
||
* ELEMENT_TYPE_BYREF, ELEMENT_TYPE_PTR or ELEMENT_TYPE_FNPTR.
|
||
* It returns the parameters specifying further information about
|
||
* the type. For example, if the type is "class Dict<String,int32>"
|
||
* then EnumerateTypeParameters will return "String" and "int32"
|
||
* in sequence.
|
||
*
|
||
*/
|
||
HRESULT EnumerateTypeParameters([out] ICorDebugTypeEnum **ppTyParEnum);
|
||
|
||
/*
|
||
* GetFirstTypeParameter can be used in those cases where the further
|
||
* information about the type involves at most one type
|
||
* parameter. You can determine this from the element type returned by
|
||
* GetType. In particular it may be used with
|
||
* ELEMENT_TYPE_ARRAY, ELEMENT_TYPE_SZARRAY, ELEMENT_TYPE_BYREF
|
||
* or ELEMENT_TYPE_PTR.
|
||
* This can only be called if the type does indeed have a type-parameter.
|
||
*/
|
||
HRESULT GetFirstTypeParameter([out] ICorDebugType **value);
|
||
|
||
/*
|
||
* GetBase returns the ICorDebugType object for the base type of this type, if it
|
||
* has one, i.e. if the type is a class type.
|
||
* For example, if
|
||
* class MyStringDict<T> : Dict<String,T>
|
||
* then the base type of "MyStringDict<int32>" will be "Dict<String,int32>".
|
||
*
|
||
* This is a helper function - you could compute this from EnumerateTypeParemeters,
|
||
* GetClass and the relevant metadata, but it is relatively painful: you would
|
||
* have to lookup the class, then the metadata of that class
|
||
* to find the "generic" base type, then instantiate this generic base type by
|
||
* looking up the type paramaters to the initial type,
|
||
* and then perform the appropriate instantiation in the case where the class
|
||
* happens to be either a generic class or a normal class with a constructed type
|
||
* as its parent. Looking up the base types is useful to implement common
|
||
* debugger functionality, e.g. printing out all the fields of an object, including its
|
||
* superclasses.
|
||
*
|
||
*/
|
||
|
||
HRESULT GetBase([out] ICorDebugType **pBase);
|
||
|
||
/*
|
||
* GetStaticFieldValue returns a value object (ICorDebugValue)
|
||
* for the given static field variable. For non-parameterized
|
||
* types, this is identical to calling GetStaticFieldValue on the
|
||
* ICorDebugClass object returned by ICorDebugType::GetClass.
|
||
* For parameterized types a static field value will be relative to a
|
||
* particular instantiation. If in addition the static field could
|
||
* possibly be relative to either a thread, context, or appdomain, then pFrame
|
||
* will help the debugger determine the proper value.
|
||
*
|
||
* This may only be used when ICorDebugType::GetType returns
|
||
* ELEMENT_TYPE_CLASS or ELEMENT_TYPE_VALUETYPE.
|
||
*/
|
||
HRESULT GetStaticFieldValue([in] mdFieldDef fieldDef,
|
||
[in] ICorDebugFrame *pFrame,
|
||
[out] ICorDebugValue **ppValue);
|
||
|
||
|
||
/*
|
||
* GetRank returns the number of dimensions in an array type
|
||
*/
|
||
|
||
HRESULT GetRank([out] ULONG32 *pnRank);
|
||
|
||
};
|
||
|
||
|
||
/* ------------------------------------------------------------------------- *
|
||
* DEPRECATED
|
||
*
|
||
* ICorDebugErrorInfoEnum interface
|
||
*
|
||
* ------------------------------------------------------------------------- */
|
||
[
|
||
object,
|
||
local,
|
||
uuid(F0E18809-72B5-11d2-976F-00A0C9B4D50C),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugErrorInfoEnum : ICorDebugEnum
|
||
{
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
HRESULT Next([in] ULONG celt,
|
||
[out, size_is(celt), length_is(*pceltFetched)]
|
||
ICorDebugEditAndContinueErrorInfo *errors[],
|
||
[out] ULONG *pceltFetched);
|
||
};
|
||
|
||
/* ------------------------------------------------------------------------- *
|
||
* AppDomainEnum interface
|
||
* ------------------------------------------------------------------------- */
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(63ca1b24-4359-4883-bd57-13f815f58744),
|
||
pointer_default(unique)
|
||
]
|
||
|
||
interface ICorDebugAppDomainEnum : ICorDebugEnum
|
||
{
|
||
/*
|
||
* Gets the next "celt" app domains in the enumeration
|
||
*/
|
||
HRESULT Next([in] ULONG celt,
|
||
[out, size_is(celt), length_is(*pceltFetched)]
|
||
ICorDebugAppDomain *values[],
|
||
[out] ULONG *pceltFetched);
|
||
|
||
};
|
||
|
||
|
||
/* ------------------------------------------------------------------------- *
|
||
* AssemblyEnum interface
|
||
* ------------------------------------------------------------------------- */
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(4a2a1ec9-85ec-4bfb-9f15-a89fdfe0fe83),
|
||
pointer_default(unique)
|
||
]
|
||
|
||
interface ICorDebugAssemblyEnum : ICorDebugEnum
|
||
{
|
||
/*
|
||
* Gets the next "celt" assemblies in the enumeration
|
||
*/
|
||
HRESULT Next([in] ULONG celt,
|
||
[out, size_is(celt), length_is(*pceltFetched)]
|
||
ICorDebugAssembly *values[],
|
||
[out] ULONG *pceltFetched);
|
||
|
||
};
|
||
|
||
/* ------------------------------------------------------------------------- *
|
||
* BlockingObjectEnum interface
|
||
* ------------------------------------------------------------------------- */
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(976A6278-134A-4a81-81A3-8F277943F4C3),
|
||
pointer_default(unique)
|
||
]
|
||
|
||
interface ICorDebugBlockingObjectEnum : ICorDebugEnum
|
||
{
|
||
/*
|
||
* Gets the next "celt" blocking objects in the enumeration
|
||
*/
|
||
HRESULT Next([in] ULONG celt,
|
||
[out, size_is(celt), length_is(*pceltFetched)]
|
||
CorDebugBlockingObject values[],
|
||
[out] ULONG *pceltFetched);
|
||
|
||
};
|
||
|
||
|
||
#pragma warning(push)
|
||
#pragma warning(disable:28718)
|
||
// Represent data for an Managed Debugging Assistant (MDA) notification. See the MDA documentation for MDA-specific information like:
|
||
// - enabling / disabling MDAs
|
||
// - MDA naming conventions
|
||
// - What the contents of an MDA look like, schemas, etc.
|
||
[
|
||
object,
|
||
local,
|
||
uuid(CC726F2F-1DB7-459b-B0EC-05F01D841B42),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugMDA : IUnknown
|
||
{
|
||
// Get the string for the type of the MDA. Never empty.
|
||
// This is a convenient performant alternative to getting the XML stream and extracting
|
||
// the type from that based off the schema.
|
||
HRESULT GetName(
|
||
[in] ULONG32 cchName,
|
||
[out] ULONG32 * pcchName,
|
||
[out, size_is(cchName), length_is(*pcchName)] WCHAR szName[]);
|
||
|
||
// Get a string description of the MDA. This may be empty (0-length).
|
||
HRESULT GetDescription(
|
||
[in] ULONG32 cchName,
|
||
[out] ULONG32 * pcchName,
|
||
[out, size_is(cchName), length_is(*pcchName)] WCHAR szName[]);
|
||
|
||
// Get the full associated XML for the MDA. This may be empty.
|
||
// This could be a potentially expensive operation if the xml stream is large.
|
||
// See the MDA documentation for the schema for this XML stream.
|
||
HRESULT GetXML(
|
||
[in] ULONG32 cchName,
|
||
[out] ULONG32 * pcchName,
|
||
[out, size_is(cchName), length_is(*pcchName)] WCHAR szName[]);
|
||
|
||
// Get the flags associated w/ the MDA. New flags may be added in future versions.
|
||
typedef enum CorDebugMDAFlags
|
||
{
|
||
// If this flag is high, then the thread may have slipped since the MDA was fired.
|
||
MDA_FLAG_SLIP = 0x2
|
||
} CorDebugMDAFlags;
|
||
HRESULT GetFlags([in] CorDebugMDAFlags * pFlags);
|
||
|
||
// Thread that the MDA is fired on. We use the os tid instead of an ICDThread in case an MDA is fired on a
|
||
// native thread (or a managed thread that hasn't yet entered managed code and so we don't have a ICDThread
|
||
// object for it yet)
|
||
HRESULT GetOSThreadId([out] DWORD * pOsTid);
|
||
};
|
||
#pragma warning(pop)
|
||
|
||
/* ------------------------------------------------------------------------- *
|
||
* Edit and Continue interfaces
|
||
* DEPRECATED
|
||
* ------------------------------------------------------------------------- */
|
||
#pragma warning(push)
|
||
#pragma warning(disable:28718) /* suppress warning 28718 for interface ICorDebugEditAndContinueErrorInfo */
|
||
/*
|
||
* DEPRECATED
|
||
*
|
||
* ICorDebugEditAndContinueErrorInfo
|
||
*
|
||
*/
|
||
[
|
||
object,
|
||
local,
|
||
uuid(8D600D41-F4F6-4cb3-B7EC-7BD164944036),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugEditAndContinueErrorInfo : IUnknown
|
||
{
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
HRESULT GetModule([out] ICorDebugModule **ppModule);
|
||
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
HRESULT GetToken([out]mdToken *pToken);
|
||
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
HRESULT GetErrorCode([out]HRESULT *pHr);
|
||
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
HRESULT GetString([in] ULONG32 cchString,
|
||
[out] ULONG32 *pcchString,
|
||
[out, size_is(cchString),
|
||
length_is(*pcchString)] WCHAR szString[]);
|
||
}
|
||
#pragma warning(pop)
|
||
|
||
/*
|
||
* DEPRECATED
|
||
*
|
||
* ICorDebugEditAndContinueSnapshot
|
||
*/
|
||
|
||
[
|
||
object,
|
||
local,
|
||
uuid(6DC3FA01-D7CB-11d2-8A95-0080C792E5D8),
|
||
pointer_default(unique)
|
||
]
|
||
interface ICorDebugEditAndContinueSnapshot : IUnknown
|
||
{
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
HRESULT CopyMetaData([in] IStream *pIStream, [out] GUID *pMvid);
|
||
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
HRESULT GetMvid([out] GUID *pMvid);
|
||
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
HRESULT GetRoDataRVA([out] ULONG32 *pRoDataRVA);
|
||
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
HRESULT GetRwDataRVA([out] ULONG32 *pRwDataRVA);
|
||
|
||
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
HRESULT SetPEBytes([in] IStream *pIStream);
|
||
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
HRESULT SetILMap([in] mdToken mdFunction, [in] ULONG cMapSize,
|
||
[in, size_is(cMapSize)] COR_IL_MAP map[]);
|
||
|
||
/*
|
||
* DEPRECATED
|
||
*/
|
||
HRESULT SetPESymbolBytes([in] IStream *pIStream);
|
||
};
|
||
|
||
|
||
/* ------------------------------------------------------------------------- *
|
||
* Library definition
|
||
* ------------------------------------------------------------------------- */
|
||
|
||
[
|
||
uuid(53D13620-F417-11d1-9762-A63826A4F255),
|
||
version(1.0),
|
||
helpstring("Common Language Runtime Debugging 1.0 Type Library")
|
||
]
|
||
library CORDBLib
|
||
{
|
||
importlib("stdole32.tlb");
|
||
|
||
// There should be no co-class for V2.0 CorDebug at all.
|
||
// Clients should create the ICorDebug object using the shim API
|
||
// CreateDebuggerInterfaceFromVersion defined in mscoree.idl.
|
||
// This guid here is the same as the v1.1 guid for setup / breaking-change purposes.
|
||
[
|
||
uuid(6fef44d0-39e7-4c77-be8e-c9f8cf988630)
|
||
]
|
||
coclass CorDebug
|
||
{
|
||
[default] interface ICorDebug;
|
||
};
|
||
|
||
[
|
||
uuid(211f1254-bc7e-4af5-b9aa-067308d83dd1)
|
||
]
|
||
coclass EmbeddedCLRCorDebug
|
||
{
|
||
[default] interface ICorDebug;
|
||
};
|
||
|
||
interface ICorDebugReferenceValue;
|
||
interface ICorDebugStringValue;
|
||
interface ICorDebugGenericValue;
|
||
interface ICorDebugBoxValue;
|
||
interface ICorDebugArrayValue;
|
||
interface ICorDebugILFrame;
|
||
interface ICorDebugInternalFrame;
|
||
interface ICorDebugInternalFrame2;
|
||
interface ICorDebugNativeFrame;
|
||
interface ICorDebugNativeFrame2;
|
||
interface ICorDebugRuntimeUnwindableFrame;
|
||
|
||
interface ICorDebugManagedCallback2;
|
||
interface ICorDebugAppDomain2;
|
||
interface ICorDebugAssembly2;
|
||
interface ICorDebugProcess2 ;
|
||
interface ICorDebugStepper2 ;
|
||
interface ICorDebugThread2 ;
|
||
interface ICorDebugThread3 ;
|
||
interface ICorDebugILFrame2;
|
||
interface ICorDebugModule2 ;
|
||
interface ICorDebugFunction2;
|
||
interface ICorDebugClass2 ;
|
||
interface ICorDebugEval2 ;
|
||
interface ICorDebugValue2;
|
||
interface ICorDebugObjectValue2;
|
||
interface ICorDebugHandleValue;
|
||
interface ICorDebugHeapValue2;
|
||
|
||
interface ICorDebugModule3;
|
||
};
|