本页内容
简介
在过去的几个月中,我曾与许多存在调试问题的用户一起工作,他们之中有一部分来自
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
对象共享出来,其他机器上的任何匹配用户(具有相同用户名和相同密码)都可能可以访问您的共享对象。
我极力建议,如果您要使用这一变通方法,则请确保所有用户帐户都具有强密码,否则应该设置一个网络孤岛来调试机器,以防止恶意攻击。
|