将此方法与远程调试结合使用

有时从内核调试器控制用户模式调试器并同时使用用户模式调试器作为调试服务器很有用。

例如,当用户模式符号位于符号服务器上时,此配置就非常有用。 在从内核调试器控制用户模式调试器的标准配置中,两个调试器的交互可能会导致同步中的微小失误,而这些失误可能会阻止符号服务器身份验证。 此处所述的更复杂的配置可以避免此问题。

注意,在描述此方案时, 目标应用程序 是指正在调试的用户模式应用程序,目标计算机是指包含目标应用程序和 CDB 或 NTSD 进程的计算机,而主计算机是指包含内核调试器的计算机。

若要使用此技术,必须执行以下操作:

  1. 使用 -ddefer 和 -server 命令行选项在目标计算机上启动 NTSD 或 CDB,并指定所需的传输选项。 -server 选项必须是命令行上的第一个参数。

    例如,可以使用以下语法附加到正在运行的进程。

    ntsd -server ServerTransport -ddefer [-y UserSymbolPath] -p PID 
    

    或者,可以使用以下语法启动新进程作为目标。

    ntsd -server ServerTransport -ddefer [-y UserSymbolPath] ApplicationName 
    

    如果要将其安装为事后调试器,应使用以下语法。 请注意,必须手动编辑注册表才能安装包含 -server 参数的事后调试器;有关详细信息,请参阅启用事后调试

    ntsd -server ServerTransport -ddefer [-y UserSymbolPath] 
    

    有关可用传输选项的信息,请参阅激活调试服务器

  2. 在主计算机上启动 WinDbg 或 KD,就像要调试目标计算机一样,但实际上不会中断目标计算机。 若要使用 WinDbg,请使用以下语法。

    windbg [-y KernelSymbolPath] [-k ConnectionOptions] 
    

    有关此步骤的详细信息,请参阅使用 WinDbg 的实时内核模式调试(经典版)

  3. 使用与启动服务器相同的传输选项,将 WinDbg 或 CDB 作为调试客户端启动。 此调试客户端可以在主机或第三台计算机上运行。

    cdb -remote ClientTransport 
    

    有关此步骤的详细信息,请参阅激活调试客户端

  4. 调试器运行并且Input>提示出现在内核调试器中后,使用.sleep(暂停调试器)命令暂停调试器,让目标计算机运行几秒钟。 这为目标计算机提供了处理远程传输协议的时间,从而在用户模式远程服务器和远程客户端之间建立连接。

如果使用 CDB 作为用户模式调试器,则与 CDB 关联的命令提示符窗口将保持锁定,在继续调试时不可用。 如果使用 NTSD,即使 NTSD 在目标计算机上具有与之关联的进程 ID,也不会创建其他窗口。

切换模式主题中描述的四种模式及其之间的切换方法在此组合方案中适用,但存在以下差异:

  • 有两种不同的用户模式调试模式。 目标计算机运行时,调试服务器由调试客户端控制,就像在任何其他远程调试会话中一样;这称为远程控制用户模式调试。 当内核模式调试器损坏到目标计算机并显示 Input> 提示时,用户模式调试器由内核调试器控制;这称为 内核控制的用户模式调试

  • 这两种模式永远不会同时可用。 当内核调试器接入目标计算机时,即使用户模式调试器处于活动状态,目标计算机也无法处理远程传输协议,因此用户模式调试器无法通过此连接接收远程输入。

  • 如果用户模式符号位于符号服务器上,任何需要访问符号的调试器命令都应在远程控制的用户模式调试模式下发出。

  • 若要从内核控制的用户模式调试切换到远程控制的用户模式调试,请使用 .sleep(暂停调试器)命令。 当用户模式调试器从睡眠命令唤醒时,它将处于远程控制的用户模式调试模式。

  • 若要从远程控制的用户模式调试切换到内核模式调试,请从 Input> 提示输入任何命令。 如果此提示不可见,请切换到内核模式调试,然后在 kd> 提示符处使用 g (Go) 命令。

在内部,以 -ddefer 启动的用户模式调试器优先于调试客户端的输入,其次才是来自内核调试器的输入。 但是,同时输入之间永远不会发生冲突,因为当内核调试器闯入目标计算机时,远程连接不可用。