A debug engine (DE) works with the interpreter or operating system to provide debugging services such as execution control, breakpoints, and expression evaluation. The DE is responsible for monitoring the state of a program being debugged. To do accomplish this, the DE uses whatever methods are available to it in the supported runtime, whether from the CPU or from APIs supplied by the runtime.
For example, the common language runtime (CLR) supplies mechanisms to monitor a running program through the ICorDebugXXX interfaces. A DE that supports the CLR uses the appropriate ICorDebugXXX interfaces to keep track of a managed code program being debugged. It then communicates any changes of state to the session debug manager (SDM), which forwards such information to the Visual Studio IDE.
A debug engine targets a specific runtime, that is, the system in which the program being debugged runs. The CLR is the runtime for managed code, and the Win32 runtime is for native Windows applications. If the language you create can target one of these two runtimes, Visual Studio already supplies the necessary debug engines. All you have to implement is an expression evaluator.
The monitoring services are implemented through the DE interfaces and can cause the debug package to transition between different operational modes. For more information, see Operational Modes. There is typically only one DE implementation per run-time environment.
While there are separate DE implementations for Transact-SQL and JScript, VBScript and JScript share a single DE.
Visual Studio debugging enables debug engines to run one of two ways: either in the same process as the Visual Studio shell, or in the same process as the target program being debugged. The latter form usually occurs when the process being debugged is actually a script running under an interpreter, and the debug engine must have intimate knowledge of the interpreter in order to monitor the script. Note that in this case, the interpreter is actually a runtime; debug engines are for specific runtime implementations. In addition, implementation of a single DE can be split across process and machine boundaries (for example, remote debugging).
The DE exposes the Visual Studio debugging interfaces. All communication is through COM. Whether the DE is loaded in-process, out-of-process, or on another computer, it does not affect component communication.
The DE works with an expression evaluator component to enable the DE for that particular run time to understand the syntax of expressions. The DE also works with a symbol handler component to access the symbolic debug information generated by the language compiler. For more information, see Expression Evaluator and Symbol Provider.