| 本页内容简介在过去的几个月中,我曾与许多存在调试问题的用户一起工作,他们之中有一部分来自 
                    Microsoft 
                    内部。我发现,如果用户能得到正确的诊断,则很多常见的错误和问题便迎刃而解。因此,我写了这篇文章,旨在向用户提供在使用调试器时能帮助他们解决问题的信息。 本文档包含: 
                      
                        
                          | • | 错误消息对话框或错误情况描述 |  
                          | • | 上述错误的原因。 |  
                          | • | 上述问题的解决方法。 |  在此,我对 VCS 
                    调试器团队和帮助我完成本文及向我提供精彩反馈的人士表示感谢。 ASP.NET调试。注 
                    如果在本部分中找不到需要的错误消息,请查看处理常规调试问题部分或处理远程调试问题部分。 消息:无法在 Web 服务器中启动调试。 
                        图 1. 
                      无法启动调试错误消息 
                       原因 1:未将 IIS 应用程序配置为使用 Integrated 
                    Windows Authentication。确保已选中“Authentication 
                    Method”对话框中的 Integrated Windows 
                    Authentication 复选框,如图 2 所示。 
                        图 2. 
                      启用集成身份验证 
                       原因 2:检查 IIS 的 Enable HTTP Keep 
                    Alive 
                    选项。如果它是关闭的,则可能需要将其打开,再尝试调试。 消息:您没有调试服务器的权限。 
                        图 3. 无调试权限 
                       原因 1:确保已启用 Integrated Windows 
                    Authentication。可能的原因是仅为 IIS 的 
                    Directory 安全启用了 Basic authentication。 原因 2:如果您在使用 Integrated 
                    Windows Authentication,则需要确保您的用户帐户能够完全控制 
                    IIS 的目录。 原因 3:如果使用完整的机器名(如 machinename.domainname.something)创建 
                    Web 项目,则该 Web 站点会被识别为 Internet 
                    站点。因此,Internet Explorer 
                    的默认设置将对登录行为产生影响。在这种情况下,您需要使用当前帐户在具有 
                    IE 设置的“Internet”区域启用登录。 然而,这不是 Internet Explorer 
                    的默认设置,因此最好仅使用机器名来创建项目,将图 
                    4 用作 Security Settings 的指南。 
                        图 4. 设置 Internet 
                      Explorer 身份验证 
                       消息:发送调试 HTTP 
                    请求时发生服务器端错误。 
                        图 5. 
                      调试期间的服务器端错误 
                       原因 1:Web 
                    应用程序没有应用程序名。为此,请使用 IIS 
                    MMC 来检查 Web 项目的属性,确保 Web 
                    项目具有应用程序名。当图 6 
                    中的红色轮廓出现时,应该出现应用程序名。 
                        图 6. 设置应用程序名 
                       原因 2:如果使用的是 NTFS 
                    文件格式,则确保“aspnet”具有“wwwroot”或虚拟目录文件夹上的适当权限,才能访问和写入这些文件夹。 消息:没有对项目进行配置以接受调试。 
                        图 7. 
                      未针对调试配置项目 
                       如果出现这一错误消息,则需要针对调试配置 
                    Web。为此,需要在 web.config 文件中设置 debug = 
                    true。此文件位于 Web 项目文件夹中。 您可以启动调试,同时不出现错误消息,但是不能到达断点。 您使用 F5 
                    键启动了调试,看起来好像正确启动了调试并且也正确启动了 
                    Internet Explorer,但是您不能到达代码隐藏的代码中的断点。 原因 1: 在项目属性中未启用 Asp.net 
                    调试。按照图 8 所示将该项设置为 True。 
                        图 8. 启用 ASP.NET 调试 
                       在 VB 项目中,UI 
                    有所不同,但可以轻松地识别等效项。 原因 2:请确保使用匹配的调试符号文件加载期望的 
                    DLL。可以使用 Modules 
                    窗口来检查这一点。 消息:未正确安装调试器。 
                        图 9. 
                      未正确安装调试器 
                       如果看到这一问题,请在 Console Application 
                    项目中检查调试功能。如果控制台应用程序项目显示如图 
                    10 所示的错误消息,则表示未正确安装 .NET 
                    Framework 应用程序。 
                        图 10. 无法启动调试 
                       需要通过执行“regsvr32 mscordbi.dll”来手动注册“mscordbi.dll”。 消息:服务器不支持对 ASP.NET 或 ATL 
                    服务器应用程序的调试。 
                        图 11. 无法启动调试 
                       如果您在机器上安装了 Windows XP Pro 或 Windows 
                    2000 Pro,则可能需要考虑 Visual Studio 7 和 IIS 
                    之间的安装顺序。如果在 Visual Studio 7 
                    之后安装 IIS,则会发生这一错误。在这种情况下,请使用“aspnet_regiis.exe 
                    –i”注册“aspnet_isapi.dll”。 消息:访问被拒绝。检验您是否是管理员或某个组成员。 
                        图 12. 访问被拒绝 
                       您可能不是该计算机上 Debugger Users 
                    组的成员。将您的用户帐户添加到计算机上的 
                    Debugger Users 组中即可解决此错误。 要将您的用户帐户添加到 Debugger Users 
                    组中,需要执行以下操作: 
                      
                        
                          | 1. | 作为 Administrator 登录。 |  
                          | 2. | 运行 Administrator tools 中的 Computer 
                            management。 |  
                          | 3. | 选择 Local users and groups\groups 
                            节点。 |  
                          | 4. | 双击右边窗格中的 Debugger Users 
                            组。 |  
                          | 5. | 单击 Debugger users properties 
                            对话框中的 Add 按钮。 |  
                          | 6. | 键入用户帐户并单击 OK。 |  消息:无法启动 ASP.NET 或 ATL 
                    服务器调试。 
                        图 13. 未安装ASP.NET 或 
                      ATL 
                       原因 1:您可能安装了 IIS Lockdown 
                    工具。如果这样,则查找 urlscan.ini 
                    文件,并将 DEBUG(区分大小写)添加到 [allowverbs] 
                    部分中。 原因 2:如果将域控制器用作服务器,并且项目是使用机器名(非完整域名)创建的,则可能需要将项目的 
                    URL 更改为完整域名。 原因 3:如果将 IIS 设置为使用专用 IP(例如 
                    Web site identification,可以在 IIS MMC 的 IIS 
                    设置中找到这一选项),则可能看到这条错误消息。在这种情况下,需要更改项目名,直接使用 
                    IP 地址。对于现有项目,需要更改项目以使用 
                    IP 地址,而不用通过编辑 .sln 文件和 .webinfo 
                    文件使用机器名。 原因 4:web.config 文件的 
                    中的值太大。默认单位是千字节而非字节,因此如果更改此数字,使用了错误的单位,则可能导致调试问题。 消息:访问被拒绝。 
                        图 14. 访问被拒绝 
                       原因:您可能是 Debugger Users 
                    组的成员,但是您不具有调试 aspnet 
                    辅助进程的权限,因为您不是 aspnet 
                    用户帐户或 Administrators 
                    组的成员。将您的用户帐户添加到机器上的 Administrators 
                    组即可解决此问题。 无法使用包括文件进行调试 在 ASPX 
                    中,无法使用包括文件进行调试。将旧的 ASP 
                    项目转换为 ASPX 时,往往产生包括文件。 如果通过 
                    包括文件,则可能无法正确调试该包括文件。您需要使用 
                    来代替。 更改密码后,需要注销/登录才能进行 
                    ASP.NET 调试。 更改密码后,需要注销,然后再登录才能正确进行 
                    ASP.NET 调试。 安装 Windows2000 SP4 后,ASP.NET 
                    调试不能运行,同时显示消息“访问被拒绝”。 此问题的解决方法是,使用 regsvr32 –i 
                    aspnet_isap.dll 重新注册 aspnet_isap.dll。 仅在首次加载页面时遇到断点。 针对这一特定问题,可能存在多种原因,但是最大的可能性是您在 
                    web.config 文件中设置了页面缓存选项。 如果在 web.config 中看到类似于 
                    的内容,则需要将值设置为“False”,以关闭 
                    Web 
                    页面缓存。更改该设置并刷新页面后,可能遇到断点。 您需要共享 Web 
                    服务器以进行调试,但是不想让其他用户成为计算机管理员。 在 Visual Studio .NET 
                    中,以下二者可以确定用户是否可以进行调试。其中之一是 
                    Debugger Users 
                    组,另一个是用户权限,如管理员、Power User 
                    或 SEDebug。 Debugger Users 组确定用户是否可以访问 VS 
                    调试组件(主要是 MDM-Machine Debug Manager,Visual 
                    Studio 
                    的一部分),所以成为该组的成员意味着保证可以访问 
                    MDM。因此在这一点上,您可以调试开放进程并查看机器上的进程列表。 不过在此之后,您是否可以调试其他用户的进程取决于您的权限。例如,如果您想调试别人的本地进程,则需要具有 
                    SEDebug 权限.针对其他用户的托管进程,您应该是该机器上的管理员,才有权进行调试。 因为存在这一限制,所以在您的方案中,应该授予学生管理员权限。否则,默认情况下无法对 
                    ASP.NET 辅助进程进行调试。 我们有一种变通方法。Cassini 是一个独立的小型 ASP.NET 服务器。对学生来说,他们可以使用 Cassini 
                      进行开发,稍后将开发结果部署到实际服务器上来提交结果。 常规调试这些案例基于 Console application 
                    项目类型。 消息:无法启动调试。 
                        图 15. 无法启动程序 
                       导致图 15 
                    中所示问题的原因是没有正确注册 mscordbi.dll。此问题的补救办法是手动注册该文件。 消息:无法启动调试。访问被拒绝。 
                        图 16. 
                      拒绝访问错误消息 
                       确保正确启动 Machine Debugger Manager 
                    服务,并且确保您是 Debugger Users 或 Administrators 
                    的成员。 我可以启动托管调试,但是 PDB 
                    不加载,并且不能遇到任何断点。 如果正确启动了调试器,但不能遇到任何断点,则您可能需要检查 
                    diasymreader.dll 
                    的安装。可能没有注册该文件。要注册该文件,需要执行以下操作: regsvr32 \diasymreader.dll
 托管调试不运行 在进程创建 CLR 对象前,以 CLR 
                    模式连接本地进程。托管调试不运行。 解决方案 1:在进程中使用了 CLR 
                    代码后再连接进程。 解决方案 2:以 InterOp 
                    模式连接进程。在这种情况下,不必在调用 
                    CLR 代码之后再连接进程。 托管调试器不响应 使用托管代码启动调试时,调试器不响应。 解决方案:确保已停止并禁用 .NET 
                    FrameworkSupport 
                    服务(仅停止该服务还不够)。 如果没有运行 .NET FrameworkSupport 
                    服务,则禁用 IIS admin 服务。 使用 C# 代码单步调试不正确 考虑以下代码: string someStr; 
someStr = "SomeValue"; 
if(someStr == null) 
  Console.WriteLine("what's up?"); 
try 
{ 
} 
catch(Exception e) 
{ 
}
如果使用此代码,则会看到遇到“if”语句时,指令指针将移动到“if”语句体 
                    (Console.WriteLine("what's up?");)。 这不是一个调试器 bug,而是一个众所周知的 
                    try catch 
                    块调试信息问题。请参见以下调试器中 try 
                    catch 块示例的反汇编代码。 if(someStr == null) 
a cmp        dword ptr [ebp-18h],0 
e jne        C 
Console.WriteLine("what's up?"); 
 mov        ecx,dword ptr ds:[01C50070h] 
 call       dword ptr ds:[02F0257Ch] 
c jmp        
catch(Exception e) 
e mov        dword ptr [ebp-1Ch],eax 
 call       C0846 
 jmp        
} 
 nop      
值没有匹配时,指令指针移动到 0000003c jmp 
                    行,但是该行已经错误地与“if”语句体相匹配。当代码功能正确时,显示就不正确了。 因果性调试:Web 服务客户端和 Web 服务之间的步骤无法从 Web 服务客户端到 Web 
                    服务设置调试 默认设置不允许从 Web 服务客户端进入 Web 
                    服务。它的运行方式类似 step-over。 ASPNET 辅助进程(aspnet_wp.exe 或 w3wp.exe)在“aspnet”或“network 
                    service”用户帐户之下运行,而这些帐户没有通过 
                    DCOM 访问 MDM 
                    的权限。因此,需要将这些帐户添加到 Debugger 
                    Users 组中。 启用 Web 
                    服务模拟后,无法再使用因果性步骤。 使用“web.config”为 Web 
                    服务启用模拟时,不能从 Web 
                    服务客户端代码进入 Web 
                    服务代码。因为,它的运行方式类似于 step 
                    over。 您需要执行以下操作来更正客户端和服务之间的步骤。 
                      
                        
                          | • | 关闭 IIS 中的 Anonymous access。 |  
                          | • | 更改客户端代码,将凭据设置为 Web 
                            服务,如下所示: |  
                          | • | Service1 obj = new Service1(); |  
                          | • | obj.Credentials = 
                            System.Net.CredentialCache.DefaultCredentials; |  在此之后,您将能够从客户端进入 Web 
                    服务。 这些操作是必需的,因为当您进入 Web 
                    服务时,某些 .NET Framework 
                    组件需要使用系统级调试器组件 (MDM) 
                    来共同创建它。如果不能提供正确的凭据,则此步骤将失败。如果没有这些正确的凭据,“step 
                    into”的运行将类似于“step over”。 调试器挂起 如果 Web 服务客户端代码在 STA (Single Thread 
                    Apartment) 
                    模型中运行,并且它在等待异步调用完成,如下所示: Service1 obj = new Service1(); 
System.IAsyncResult ar = obj.BeginHelloWorld(new System.AsyncCallback(Class1.Handle),obj); 
while(ar.IsCompleted != true) 
{ 
  System.Threading.Thread.Sleep(1000); 
}
则调试器将挂起。发生此挂起操作,原因在于调试器中的代码已锁定一个调试器组件。解决方案 
                    1 是更改代码以使用与事件或 mutex 
                    同步的线程。另一个解决方案是注销 csm.dll。第二个解决方案禁用 
                    causality 步骤(从 Web 服务客户端代码到 Web 
                    服务方法的步骤)。您可能需要手动连接 
                    aspnet_wp.exe 才能调试 Web 服务。 远程调试无法查看远程机器上的任何进程 确保在远程机器上安装了 Remote full debug 
                    设置,并且您是 Debugger Users 组的成员。 因 RPC 问题而无法连接到远程机器 以下信息摘自 Mike Clay 撰写的 KB 文章。 如果通过“Processes”对话框连接到远程机器上时看到以下错误消息: Error while trying to run project: Unable to start debugging on the 
web server. Not enough storage is available to complete this operation.
 或者在进行 ASP.NET 调试期间看到这一消息: Error while trying to run project: Unable to start debugging on the web
server. Unable to map the debug start page URL to a machine name.
 则确保 RPC 
                    在您的机器与远程机器之间正确运行。下面的行为可能导致 
                    RPC 问题: 
                      
                        
                          | • | 通过防火墙进行调试。Microsoft 
                            不建议或支持通过防火墙的远程 ASP.NET 
                            调试。解决此问题最好的方式是,使用“终端服务”登录远程服务器并在本地进行调试。 |  
                          | • | RPC 
                            的一种常见故障是无力解析远程机器名。RPC 
                            依靠名称解析在计算机之间通信。如果未能将远程服务器机器名解析为正确的 
                            IP 地址,则可能发生错误。 |  
                          | • | RPC 
                            通信只能单向流动,另一个方向却不行。RPC 
                            通信必须能够从用于调试的机器到达远程服务器,并从远程服务器返回用于调试的机器,这样才能成功进行远程调试。确保以双向方式启用 
                            RPC 通信。 |  要分析 RPC,可以使用 RPCPing 工具。 远程调试工作组中的机器失败 当您的两台 Windows XP Pro 
                    机器都不在域中但在工作组中时,将发生这种情况。在它们之间进行远程调试时,您根本无法访问远程机器。 在工作组环境中,您需要确保两台机器具有相同的用户帐户名和相同的密码。否则,DCOM 
                    进行身份验证时将失败。 另外,在 Windows XP Pro 上,将 Sharing and 
                    security model for local accounts 
                    的默认安全设置设置为现在允许共享。下面是更改此设置的步骤: 
                      
                        
                          | 1. | 运行管理员工具中的 Local Security 
                            Settings。 |  
                          | 2. | 选择 Security settings\Local 
                            policies\Security 选项。 |  
                          | 3. | 将 Network access : Sharing and Security 
                            model for local accounts 从 Guest only - 
                            local users authenticate as Guest 更改为 Classic 
                            - local users authenticate as themselves。 |  
                          | 4. | 重新启动计算机。 |  应该将此更改应用于进行远程调试的两台机器。 更改设置后,即可使用同一名称的用户帐户在两台机器上进行远程调试。请确保每台机器上的用户帐户都具有密码。在某些情况下,没有实际密码机器不能运行。 然而,因为更改了安全模型的默认设置,所以可能公开下面的内容: 
                      
                        
                          | • | 意外的文件共享 |  
                          | • | 意外的 DCOM 组件共享。 |  在进行这一更改之前,从远程机器到您的机器的任何种类的连接都是以 
                    Guest 身份进行的;但更改后,他/她即可接受使用本地用户帐户的身份验证。因此,在调试案例中,如果将一个文件夹或 
                    DCOM 
                    对象共享出来,其他机器上的任何匹配用户(具有相同用户名和相同密码)都可能可以访问您的共享对象。 我极力建议,如果您要使用这一变通方法,则请确保所有用户帐户都具有强密码,否则应该设置一个网络孤岛来调试机器,以防止恶意攻击。 
                   |