调试会话和执行模型
调试器引擎可以同时调试多个目标。 调试会话在引擎获取目标时开始,并一直持续到所有目标被丢弃为止。 当目标正在执行时,调试会话 不可访问 ;当当前目标挂起时 可访问 调试会话。 该引擎只能用于在访问会话时检查和操作目标。
调试器的main循环通常包括设置执行状态、调用 WaitForEvent 方法以及处理生成的事件。 调用 WaitForEvent 时,会话变得不可访问。
当目标中发生事件时,引擎将挂起所有目标,并且会话变为可访问。 然后,引擎通知事件的事件回调,并遵循事件筛选器规则。 事件回调和事件筛选器确定目标中的执行方式。 如果他们确定引擎应中断调试器, 则 WaitForEvent 方法将返回,并且会话仍可访问;否则,引擎将以事件回调和事件筛选器确定的方式继续执行目标,会话将再次变得不可访问。
在 WaitForEvent 调用期间,特别是在通知事件回调和处理筛选规则时,引擎处于称为“等待内”的状态。 处于此状态时,无法调用 WaitForEvent , (它不是可重入) 。
在目标中启动执行涉及两个步骤:设置执行状态,然后调用 WaitForEvent。 可以使用 SetExecutionStatus 方法或通过执行设置执行状态的调试器命令(例如, g (Go) 和 p (Step) )来设置执行状态 。
如果一系列调试器命令一起执行,例如,“g; ?@$ip“--如果命令不是序列中的最后一个命令,则要求在目标中执行的任何命令之后,将发生 隐式等待 。 当调试器引擎处于“等待中”状态时,无法发生隐式等待;在这种情况下,命令的执行将停止,当前命令(试图导致隐式等待的命令)将被解释为指示目标中的执行方式。 其余命令将被丢弃。
注意 确定会话是可访问还是不可访问时,目标 (有限执行时,引擎会将单步执行) 视为执行。 受限执行完成后,会话将变为可访问。
主机引擎
远程调试时,可以使用调试器引擎的多个实例。 正是其中一个实例维护调试会话;此实例称为 主机引擎。
所有调试器操作都相对于主机引擎,例如符号加载和扩展加载。