控制执行

调试引擎(DE)通常将下列事件之一作为最后一个启动事件发送:

  • 入口点事件(如果附加到新启动的程序)

  • 当附加到已经在运行的程序时,触发加载完成事件。

    这两个事件都是停止事件,这意味着 DE 通过 IDE 等待用户的响应。 有关详细信息,请参阅 作模式

停止事件

当停止事件发送到调试会话时:

  1. 可以从事件接口获取包含当前指令指针的程序和线程。

  2. IDE 确定并在编辑器中高亮显示当前的源代码文件及其位置。

  3. 调试会话通常通过调用程序的 Continue 方法响应此第一个停止事件。

  4. 然后,程序会继续运行,直到遇到停止条件,例如触发一个断点。 在这种情况下,DE 会将断点事件发送到调试会话。 断点事件是一个停止事件,DE 会再次等待用户响应。

  5. 如果用户选择单步进入、单步越过或单步退出函数,IDE 会提示调试会话调用程序的 Step 方法。 然后,IDE 传递步骤单元(指令、语句或行)和步骤类型(是进入函数、跳过函数还是跳出函数)。 完成该步骤后,DE 会将步骤完成事件发送到调试会话,这是一种停止事件。

    -或-

    如果用户选择从当前指令指针继续执行,IDE 会提示调试会话调用程序的 Execute 方法。 程序将恢复执行,直到遇到下一个停止条件。

    -或-

    如果调试会话要忽略特定的停止事件,调试会话将调用程序的 Continue 方法。 如果程序在遇到停止条件时正在进入、跳过或退出某个函数,则它会继续。

    以编程方式,当 DE 遇到停止条件时,它通过 IDebugEventCallback2 接口将此类停止事件(如 IDebugLoadCompleteEvent2IDebugEntryPointEvent2)发送到会话调试管理器(SDM)。 DE 传递表示程序以及包含当前指令指针的线程的 IDebugProgram2IDebugThread2 接口。 SDM 调用 IDebugThread2::EnumFrameInfo 以获取顶部堆栈帧,并调用 IDebugStackFrame2::GetDocumentContext 以获取与当前指令指针关联的文档上下文。 本文档上下文通常是源代码文件名、行号和列号。 IDE 使用这些代码突出显示包含当前指令指针的源代码。

    SDM 通常通过调用 IDebugProgram2::Continue 来响应此第一个停止事件。 程序随后继续运行,直至遇到一个停止条件,例如触发一个断点。这时,DE 会发送 IDebugBreakpointEvent2 接口 给 SDM。 断点事件是一个停止事件,DE 会再次等待用户响应。

    用户选择单步进入、单步略过或单步退出函数时,IDE 会提示 SDM 调用 IDebugProgram2::Step。 然后,IDE 会传递 STEPUNIT(指令、语句或行)和 STEPKIND,即步入、步过或步出函数。 完成此步骤后,DE 会将 IDebugStepCompleteEvent2 接口发送到 SDM,这是一个正在停止的事件。

    如果用户选择从当前指令指针继续执行,IDE 会要求 SDM 调用 IDebugProgram2::Execute。 程序将恢复执行,直到遇到下一个停止条件。

    如果调试包要忽略特定的停止事件,调试包将调用 SDM,而 SDM 则调用 IDebugProgram2::Continue。 如果程序在遇到停止条件时正在单步进入、跳过或退出某个特定功能,它会继续当前的单步操作。 这意味着程序保持单步执行状态,以便它知道如何继续。

    SDM 对 Step执行继续 进行的调用是异步的,这意味着 SDM 需要快速返回调用。 如果 DE 在 StepExecuteContinue 返回之前在同一线程上发送停止事件,SDM 将停止响应。