控制执行

调试引擎(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。 程序将恢复执行,直到遇到下一个停止条件。

    如果调试包要忽略特定的停止事件,调试包将调用调用 IDebugProgram2::Continue 的 SDM。 如果程序遇到停止条件时正在单步执行、遍历或退出某个函数,它会继续执行该步骤。 这意味着程序保持单步执行状态,以便它知道如何继续。

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