当调试程序和正在调试的进程不在同一台计算机上时,称为远程调试。远程调试可按两种方式进行,一种方式是,通过代理将一个调试程序连接到远程进程;另一种方式是,在远程计算机上运行调试程序,而在本地计算机上共享调试程序的命令行。在这种情况下,代理在远程的系统上运行,而调试程序在本地系统上运行;代理连接到进程,读取进程的内存,并将它传送到本地调试程序。使用代理的远程调试的优点是,安装简单而快速。其缺点是,容易出现网络问题,有时会导致远程计算机上的代理崩溃。因为符号只安装在本地计算机上,所以它们可能与远程计算机上的符号不匹配。因此,远程调试可能相当慢。
使用共享命令行的远程调试需要使用 remote.exe 工具,它是随 windows 2000 Customer Diagnostic and Support Tools CD 分发的。remote.exe 工具既可以作为服务器运行,也可以作为客户机运行。使用命名管道连接服务器和客户机。WSRemote.exe 是 remote.exe 的一个套接字版本/变体。Remote.exe 允许共享 STDIN(标准输入)和 STDOUT(标准输出)。在远程计算机上,可以使用下面的命令运行该远程计算机的服务器实例:
remote /s application pipename
在本地计算机上,您可以使用下面的命令将 remote.exe 作为客户机运行:
remote /c machinename pipename
这种设置非常可靠,并且能够容忍网络故障。
用户转储调试
当出现异常时,用户转储会在硬盘上创建进程的内存的一个快照。windows NT 有一种称为 DrWatson 的工具,当系统中出现异常时,它能够创建用户转储。还有一种称为 User Mode Process Dump 的调试工具。您能配置该用户转储工具,使它监视某个特定进程的异常。随后可以在调试程序(如 Windbg)中查看这样创建的用户转储文件,很轻松地对它进行分析,而不必调试实时进程。
microsoft.com/china/msdn/msdnonline/features/articles/Windebug.ASP#TOP">
使用 NTSD
NTSD 调试程序在启动时要求用户指定一个要连接的进程。使用 TLIST 或 PVIEWER,您可以获得某个现有进程的进程 ID,然后键入 NTSD -p pid 来调试这个进程。NTSD 命令行使用如下的句法:
NTSD [options] imagefile
其中,imagefile 是要调试的映像名称,options 是下面选项之一:
表 1. NTSD 映像文件选项
选项 说明 -2 打开一个用于调试字符模式的应用程序的新窗口 -d 将输出重定向到调试终端 -g 使执行自动通过第一个断点 -G 使 NTSD 在子程序终止时立即退出 o 启用多个进程的调试,默认值为由调试程序衍生的一个进程 -p 指定调试由进程 ID 标识的进程 -v 产生详细的输出例如,假设 .NETinfo.exe 的进程 ID 为 104。键入以下命令将 NTSD 调试程序连接到 inetinfo 进程 (IIS)。
NTSD -p 104
也可使用 NTSD 启动一个新进程来进行调试。例如,NTSD notepad.exe 将启动一个新的 notepad.exe 进程,并与它建立连接。
一旦连接到某个进程,您就可以用各种命令来查看堆栈、设置断点、转储内存,等等。
表 2. 常用命令
命令 含义 ~ 显示所有线程的一个列表 KB 显示当前线程的堆栈轨迹 ~*KB 显示所有线程的堆栈轨迹 R 显示当前帧的寄存器输出 U 反汇编代码并显示过程名和偏移量 D[type][<range>] 转储内存 BP[#] <address> 设置断点 BC[<bp>] 清除一个或多个断点 BD[<bp>] 禁用一个或多个断点 BE[<bp>] 启用一个或多个断点 BL[<bp>] 列出一个或多个断点使用 WinDBG
- 启动 WinDBG。
- 在 Debug 菜单上, 单击 Attach to a Process, 从列表中选择您要调试的进程,然后单击 select。
WinDBG 在命令窗口中列出与 inetinfo 进程有关的 DLL,并显示是否为某个特定的 DLL 加载了符号。这时正在调试的 inetinfo.exe 应用程序 (IIS) 被停止。要再次启动它,请在命令窗口中键入 g。
- 在命令窗口中键入 ~*kb。
这时列出此进程中的所有线程的堆栈。
- 要更改符号的路径,请在 View 菜单上单击 Options。在 Windows Debugger Options 对话框中,单击 Symbols 选项卡,在 Debug Symbols Search Path 文本框中指定符号文件的路径,然后单击 OK 按钮。
- 在命令窗口中键入 kb。
- 这时列出当前线程的堆栈。
查看当前线程的堆栈的另一种方法是,通过单击 View 菜单上的 Call Stack 来查看 Call Stack 窗口。
- 在命令窗口中键入 lm。
这时列出进程中的所有模块 (DLL),包括它们的名称和加载基地址。
- 在命令窗口中键入 q 退出。
使用 iis Exception Monitor
在下面的示例中,用 IIS Exception Monitor 连接到 inetinfo (IIS) 进程,并调试该进程。
- 单击开始,指向程序,指向 IIS Exception Monitor,然后单击 IIS Exception Monitor。
- 在 Welcome 对话框中,单击 Next。
- 在 Check Sumbols 对话框中,如果选择 yes,向导将查找 IIS 所用的文件,并确定在 %SYSTEMroot%Symbolsdll 目录中是否有匹配的文件。您也可以选择 Use Alternate Symbol Path for Exception Monitoring 来指定一个不同的符号路径。
- 选择 Yes。检查安装的 IIS Symbols,然后单击 Next。
- 在 Verify Symbols 对话框中,检查哪些 DLL 与您系统中的符号不匹配。您也可以选中 DeteRmine which symbol packages can be installed from Microsoft's Internet site 复选框,以便从 Microsoft 的 Internet 站点下载符号。这将把您带到下载页。对于我们的示例,姑且假定您已正确地安装了符号,单击 Next。
注: Verify Symbols 对话框使用 CHECKSYM.EXE 来获得它的符号信息。CHECKSYM.EXE 位于 C:ixcptmonbin 目录下。
- 在 Process Options 对话框中,您会发现三个选项。In-Process 选项指在 inetinfo 进程中运行的 IIS 应用程序(IIS 5.0 中的选项“低”)。Out-Of-Process 选项指配置为在自己的/共享的进程空间中运行的 IIS 应用程序(IIS 5.0 中的选项“高”和“中”),以及那些在 MTS/COM+ 下作为服务器程序包运行的组件。Other Process 选项本质上指在系统中运行的任何其它进程。如果将 MTS 下的一个组件注册为 "Server application/package",则它将在 dllhost.exe 进程(Windows NT 4.0 中的 mtx.exe)中运行。这样,针对每个应用程序将会有 dllhost.exe 的几个实例运行。如果您需要调试感兴趣的某个组件,则首先必须找出这个组件在其下运行的 dllhost.exe 实例,然后连接到该实例。Out-Of-Process 很有用的一个功能是,它可以按应用程序名/程序包名列出用 MTS/COM+ 注册的所有组件,因此免去了您查找正确的 dllhost.exe 实例并连接该实例的麻烦。
对于我们的示例,选择 In-Process 选项,然后单击 next。
- 这时弹出 Session Options 对话框。如果选择 Automatic,则只要有异常发生,就会生成一个日志文件。如果您选择 Manual,将提示您输入端口、用户名和密码,以便技术支持工程师能交互地解决您的问题。如果您正在通过技术支持解决一个问题,则应该主要使用这个选项。如果选中 Manual,则一旦有例外发生,web 服务器就会被挂起,并且无法接收任何 Web 请求,直到重新启动该服务器或者取消此监视会话为止。如果希望 IIS Exception Monitor 在写完日志并重新启动进程后继续监视事件,请选中 Enable Recursive Mode 复选框。如果您希望在 IIS Exception Monitor 遇到异常时收到一条弹出式消息,或者您安装了 CDO 和 SMTP 服务,则请选中 Notify Admin 复选框。指定一个完全限定的电子邮件地址,以便在检测到异常时收到一则带有 .dbl 文件格式的附件的电子邮件信息。选中 Schedule this session 复选框,您就可以预定一个 Exception Monitor 会话,使它在指定的时间或系统启动时运行。这需要安装计划任务。如果未安装计划任务,则此选项不可用。
对于我们的示例,请选选 Automatic 选项,然后单击 Next。
- 在 Start Monitoring 对话框中,单击 Run This Monitoring Session,然后单击 Next。
- Session Status 对话框列出以前监视过的、或者现在正在监视的所有进程。单击 Finish。
您将看到标题栏中为 "IIS_<Process ID>" 的一个命令提示符窗口。该窗口用来监视 inetinfo.exe 进程。一旦有异常发生, IIS Exception monitor 就会创建日志文件 (.dbl),重新启动 IIS Service,并关闭此命令提示符窗口。
日志文件在 IXCPTMONLogs 目录下。
用日志文件鉴别问题
当 IIS Exception Monitor 安装时,日志读取程序 Readlogs.exe 也会随之安装。您可以用 Readlogs 来打开刚刚生成的 .dbl 日志文件。
图 3. Readlog 对话框
当 Readlogs 打开日志文件时,它显示引起异常的线程的堆栈。如果符号安装正确,则 Readlogs 就会解析函数名,并将它们显示在 Function 栏中,如上图所示。函数名与 DLL 名之间用 "!" 符号分隔。例如,上图中的函数名 OutputDebugStringA 就驻留在 KERNEL32 DLL 中。
在分析器中,始终可以通过单击 Fault Stack 按钮来查看有故障的线程的堆栈。可以使用 << 和 >> 按钮滚动堆栈列表。您也可以选择下拉列表 Choose a Command 中的任何一个命令来执行。如果您不想看 Microsoft 的文件,则您可以将它们隐藏。这有助于您快速确认是否有第三方 DLL 包含在进程中。除了列出堆栈以外,日志文件还包含有关以下各项的信息:加载的 DLL 或模块、任何锁定及其线程 ID、以及检测到的错误。
单击 DLLs 按钮,您可以列出在此进程中加载的全部 DLL。
您可以用 Errors 按钮列出在进程运行时出现所有错误,包括警告。您也可以定制 IIS Exception Monitor 来捕获某些错误。
单击 Locks 按钮可以显示锁定及其拥有的线程 ID 的一个列表。只要一个线程想以独占方式访问某个资源,这个线程就会要求锁定此资源。当两个或多个线程同时锁定一个特定资源并等待另一个线程放弃锁定时,就会出现称为“死锁”的现象。您可以检查锁定列表以及它们拥有的线程,以确定死锁问题的可能来源。
通过单击 P.T.C. (Prior to Crash) 按钮,可以列出进程失败前的最后 20 行日志。
通过单击 Report 按钮,也可以将全部信息的一份副本以报表格式粘贴到剪贴板中。
通过单击 Sys Info 按钮,可以显示有关可用于调试的系统的一些有用信息。
通过单击 Config 按钮,可以定制读取日志以满足您的需要。
使用 User Mode Process Dump Tool
User Mode Process Dump 工具连接到某个特定的进程,并在发生异常时将进程的内存转储到硬盘中。首先,您必须运行 C:Program FilesDebuggersbinuserdump 目录下的 setup.exe 来安装 User Mode Process Dump 服务。User Mode Process Dump 安装程序是作为 DBGPLUS 套件安装的一部分安装的。
- 在 Welcome 对话框中,单击 Next。
- 在 Confirmation 对话框中,单击Finish。
- 安装程序安装了一个称为 Process Dump 的控制面板图标,可用来配置 User Dump 服务。
- 双击 Process Dump 图标调出 User Mode Process Dump Configuration 对话框。
- 单击 New,然后输入要通过用户转储工具对其进行监视的应用程序的名称。
通过创建规则,您可以定制该工具,使其只捕获某些异常。单击 Rules。
如果在该工具正在监视的进程中发生异常,它将把进程的内存转储到硬盘中。与 IIS Exception Monitor 不同,User Mode Process Dump 工具在转储进程之后并不重新启动 IIS 服务。
在 WinDBG 调试程序中能够打开并分析这样创建的用户转储,以便确定故障的原因:
- 启动 WinDBG。在 File 菜单中,单击 Open Crash Dump,并选择此故障转储文件。
- 在命令窗口中,键入 g (go) 开始调试此进程。
- 查看出现故障的堆栈,键入 kv。
调试哪个进程?
确定要连接和调试哪个进程并不容易。正像早些时候在 "Internet Information Server 的结构" 中讨论的那样,可以按几种不同的方案使用组件和 IIS 应用程序。下表根据组件类型和 IIS 配置说明应该连接哪个进程。
表 3. 组件类型和 IIS 配置
组件类型 联机处理的 IIS 应用程序 脱机处理的 IIS 应用程序 共享脱机处理的 IIS 应用程序(IIS 5.0 only) 库程序包/应用程序中的组件或不属于 MTS/COM+ 的组件连接 inetinfo 进程连接 IIS 应用程序驻留在其中的程序包/应用程序的 MTX/DLLHOST 实例 服务器程序包/应用程序中的组件连接 IIS 组件驻留在其中的程序包/应用程序的 MTX/DLLHOST 实例
当您试图调试 MTS/COM+ 下一个组件或 IIS 应用程序,而这个组件或 IIS 应用程序又是作为一个服务器程序包/应用程序安装的时,调试将变得异常复杂。在单个系统中可能运行着几个服务器程序包/应用程序,其中每一个都有自己的 MTX.exe 或 DLLHost.exe。哪一个是您需要的呢?首要任务是找出加载您要调试的组件的那个进程的 PID(进程标识符)。您可以使用 IIS Exception Monitor 来获取这个信息,在 Process Options 页中选择 Out-Of-Process 选项。
这时出现 Select Out-Of-Process Application 页,在此您可以查看按应用程序名/程序包名列出的进程,从而使确定要连接哪个 PID 变得容易了。