您的位置:首页 > 编程语言 > ASP

蛙蛙推荐:怎样调试asp.net黄页错

2008-09-16 22:29 459 查看
蛙蛙推荐:怎样调试asp.net黄页错

摘要:如果你的web应用莫名其妙的报了一个未处理异常,出现了一个黄色页面的错误,你都是如何来排错的?如果报错页面显示的调用栈上没有做任何log和trace,也没有对参数和全局变量做一些断言,你咋办?如果源码也不在你手上,你在给客户解决问题你咋办?

我们先来模拟问题,这是一个简单的页面,接受一个查询字符串,如果这个字符串能转换成整形,并且是偶数,就原样输出,如果是奇数,Page_Load方法里没有进行对handleInput方法的返回值进行是否为空的判断就直接调用ToUper的方法,所以当查询字符串为奇数的时候就会抛出未处理异常,出现大黄页,代码如下

using System;

using System.Web.UI;

namespace WebApplication1

{

public partial class TestException : Page

{

protected void Page_Load(object sender, EventArgs e)

{

try

{

string input = Request.QueryString["id"];

//这里没有判断handleInput方法的返回值

Response.Write(handleInput(input).ToUpper());

}

catch (ArgumentNullException ane)

{

Response.Write(ane.Message);

Response.End();

}

catch (ArgumentException ae)

{

Response.Write(ae.Message);

Response.End();

}

}

private static string handleInput(string input)

{

if (string.IsNullOrEmpty(input))

throw new ArgumentNullException("input", "输入数据不能为空");

int intInput;

if (!int.TryParse(input, out intInput))

throw new ArgumentException("输入数据不是整形", "input");

return intInput %2 == 0 ? intInput.ToString() : null;

//这里没有检查后置参数的值,导致该方法可返回无效值null。

}

}

}

有时候我们机器上有多个网站,每个网站使用不同的应用程序池,这就会有多个w3wp进程,我们得先确定我们的web应用的进程ID,用以下命令找出,我的机器就一个应用程序池,是1592,打开windbg,按f6附加进程

C:\Documents and Settings\Administrator>iisapp

W3WP.exe PID: 1592 AppPoolId: ASP.NET V2.0

然后按顺序来排查

1、加载SOS

.loadby sos mscorwks

2、找出空引用异常的方法表地址

!name2ee *!System.NullReferenceException

0:026> !name2ee *!System.NullReferenceException

*********************************************************************

* Symbols can not be loaded because symbol path is not initialized. *

* *

* The Symbol Path can be set by: *

* using the _NT_SYMBOL_PATH environment variable. *

* using the -y <symbol_path> argument when starting the debugger. *

* using .sympath and .sympath+ *

*********************************************************************

PDB symbol for mscorwks.dll not loaded

Module: 106f1000 (System.WorkflowServices.dll)

--------------------------------------

Module: 65ce1000 (System.Web.Services.dll)

--------------------------------------

Module: 027f1000 (SMDiagnostics.dll)

--------------------------------------

Module: 10ec1000 (System.Runtime.Serialization.dll)

--------------------------------------

Module: 64891000 (System.Configuration.dll)

--------------------------------------

Module: 65f21000 (System.Web.dll)

--------------------------------------

Module: 7a441000 (System.dll)

--------------------------------------

Module: 021e2698 (CppCodeProvider.dll)

--------------------------------------

Module: 02921000 (System.EnterpriseServices.dll)

--------------------------------------

Module: 10a11000 (System.EnterpriseServices.Wrapper.dll)

--------------------------------------

Module: 790c1000 (mscorlib.dll)

Token: 0x020000dc

MethodTable: 7931fec0

EEClass: 7914e0d0

Name: System.NullReferenceException

--------------------------------------

Module: 021e2354 (sortkey.nlp)

--------------------------------------

Module: 021e2010 (sorttbls.nlp)

--------------------------------------

Module: 021e2c04 (prcp.nlp)

--------------------------------------

Module: 695a1000 (System.Web.Mobile.dll)

--------------------------------------

Module: 021e329c (mscorlib.resources.dll)

--------------------------------------

Module: 637a1000 (System.Xml.dll)

--------------------------------------

Module: 0ea31000 (System.ServiceModel.dll)

--------------------------------------

Module: 65151000 (System.Data.dll)

--------------------------------------

Module: 5e621000 (Microsoft.JScript.dll)

--------------------------------------

Module: 021e35f0 (System.Web.resources.dll)

--------------------------------------

Module: 6c3b1000 (VJSharpCodeProvider.dll)

--------------------------------------

Module: 7ade1000 (System.Drawing.dll)

--------------------------------------

Module: 66f01000 (System.Web.RegularExpressions.dll)

--------------------------------------

Module: 100c1000 (System.ServiceModel.Web.dll)

--------------------------------------

Module: 10ba1000 (System.IdentityModel.dll)

--------------------------------------

Module: 021e2f48 (System.resources.dll)

--------------------------------------

Module: 02638280 ()

--------------------------------------

Module: 026393b4 ()

--------------------------------------

Module: 02639734 ()

--------------------------------------

Module: 10d10010 ()

--------------------------------------

Module: 026c82d4 (WebApplication1.DLL)

--------------------------------------

Module: 026c9180 ()

--------------------------------------

Module: 026c9500 ()

--------------------------------------

Module: 026c9b3c (App_Web_qt-srzwh.dll)

3、找出空引用方法表的方法描述

!dumpmt -md 7931fec0

0:026> !dumpmt -md 7931fec0

EEClass: 7914e0d0

Module: 790c1000

Name: System.NullReferenceException

mdToken: 020000dc (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)

BaseSize: 0x48

ComponentSize: 0x0

Number of IFaces in IFaceMap: 2

Slots in VTable: 21

--------------------------------------

MethodDesc Table

Entry MethodDesc JIT Name

79240bc8 79106234 PreJIT System.Exception.ToString()

79286a90 7910493c PreJIT System.Object.Equals(System.Object)

79286b00 7910496c PreJIT System.Object.GetHashCode()

792f72f0 79104990 PreJIT System.Object.Finalize()

79240bd8 7910617c PreJIT System.Exception.get_Message()

792993f0 7910618c PreJIT System.Exception.get_Data()

79744d94 791061c0 PreJIT System.Exception.GetBaseException()

792995d0 791061c8 PreJIT System.Exception.get_InnerException()

79745530 791061ec PreJIT System.Exception.get_TargetSite()

792994f0 79106200 PreJIT System.Exception.get_StackTrace()

79745460 79106214 PreJIT System.Exception.get_HelpLink()

79745440 7910621c PreJIT System.Exception.set_HelpLink(System.String)

797453a4 79106224 PreJIT System.Exception.get_Source()

79745390 7910622c PreJIT System.Exception.set_Source(System.String)

79255968 79106264 PreJIT System.Exception.GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)

79744b44 791062b4 PreJIT System.Exception.InternalToString()

79744b30 791062bc PreJIT System.Exception.GetType()

79253fc0 7919b748 PreJIT System.NullReferenceException..ctor()

797d15ec 7919b758 PreJIT System.NullReferenceException..ctor(System.String)

797d15c4 7919b764 PreJIT System.NullReferenceException..ctor(System.String, System.Exception)

797d1610 7919b770 PreJIT System.NullReferenceException..ctor(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)

4、在空引用异常对象的构造函数上设置断点

!bpmd -md 7919b748

0:026> !bpmd -md 7919b748

MethodDesc = 7919b748

Setting breakpoint: bp 797D158C [System.NullReferenceException..ctor()]

*** WARNING: Unable to verify checksum for C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\mscorlib\9adb89fa22fd5b4ce433b5aca7fb1b07\mscorlib.ni.dll

*** ERROR: Module load completed but symbols could not be loaded for C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\mscorlib\9adb89fa22fd5b4ce433b5aca7fb1b07\mscorlib.ni.dll

5、继续执行程序并测试程序

0:026> g

(638.bc8): Access violation - code c0000005 (first chance)

First chance exceptions are reported before any exception handling.

This exception may be expected and handled.

eax=00000000 ebx=02b920c4 ecx=00000000 edx=00000000 esi=06b23cec edi=02b920c4

eip=1166064f esp=1138f260 ebp=1138f2cc iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246

WebApplication1!WebApplication1.TestException.Page_Load(System.Object, System.EventArgs)+0x8f:

1166064f 3909 cmp dword ptr [ecx],ecx ds:0023:00000000=????????

*** WARNING: Unable to verify checksum for C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\webapplication1\c72f0972\f7fe4744\assembly\dl3\ab709657\703b76b7_0218c901\WebApplication1.DLL

6、查看调用栈及调用栈的参数和临时变量

0:022> !clratack -a

No export clratack found

0:022> !clrstack -a

OS Thread Id: 0xbc8 (22)

ESP EIP

1138f260 1166064f WebApplication1.TestException.Page_Load(System.Object, System.EventArgs)

PARAMETERS:

this = 0x06b235c4

sender = 0x06b235c4

e = 0x02b920c4

LOCALS:

0x1138f2a0 = 0x06b243d4

0x1138f29c = 0x00000000

0x1138f298 = 0x00000000

1138f2d8 66f2a7ff System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)

PARAMETERS:

fp = <no data>

o = <no data>

t = <no data>

e = <no data>

1138f2e8 660b2344 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)

PARAMETERS:

this = <no data>

sender = <no data>

e = <no data>

1138f2fc 660ab864 System.Web.UI.Control.OnLoad(System.EventArgs)

PARAMETERS:

this = <no data>

e = <no data>

LOCALS:

<no data>

1138f310 660ab8a3 System.Web.UI.Control.LoadRecursive()

PARAMETERS:

this = 0x06b235c4

LOCALS:

<no data>

<no data>

<no data>

1138f328 660a7954 System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)

PARAMETERS:

this = 0x06b235c4

includeStagesBeforeAsyncPoint = 0x00000001

includeStagesAfterAsyncPoint = 0x00000001

LOCALS:

0x1138f334 = 0x06b21d04

0x1138f330 = 0x00000000

0x1138f32c = 0x02a301d0

<no data>

<no data>

<no data>

<no data>

<no data>

1138f480 660a7584 System.Web.UI.Page.ProcessRequest(Boolean, Boolean)

PARAMETERS:

this = 0x06b235c4

includeStagesBeforeAsyncPoint = <no data>

includeStagesAfterAsyncPoint = 0x00000001

LOCALS:

0x1138f484 = 0x00000000

1138f4b8 660a74b1 System.Web.UI.Page.ProcessRequest()

PARAMETERS:

this = 0x06b235c4

LOCALS:

0x1138f4c0 = 0x02a9e97c

0x1138f4bc = 0x06a87bcc

0x1138f4b8 = 0x06a87bcc

1138f4f0 660a7446 System.Web.UI.Page.ProcessRequestWithNoAssert(System.Web.HttpContext)

PARAMETERS:

this = <no data>

context = <no data>

1138f4fc 660a7422 System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)

PARAMETERS:

this = <no data>

context = <no data>

1138f510 1166025e ASP.testexception_aspx.ProcessRequest(System.Web.HttpContext)

PARAMETERS:

this = 0x06b235c4

context = 0x06b21d04

1138f520 660ad8f6 System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()

PARAMETERS:

this = <no data>

LOCALS:

0x1138f528 = 0x06b21d04

<no data>

<no data>

<no data>

<no data>

<no data>

1138f554 6608132c System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)

PARAMETERS:

this = 0x02b79ab0

step = 0x02b8fb6c

completedSynchronously = 0x1138f5b0

LOCALS:

0x1138f55c = 0x00000000

<no data>

<no data>

<no data>

<no data>

1138f594 6608c3a3 System.Web.HttpApplication+ApplicationStepManager.ResumeSteps(System.Exception)

PARAMETERS:

this = 0x02b8c614

error = <no data>

LOCALS:

0x1138f5b4 = 0x00000000

0x1138f5b0 = 0x00000001

0x1138f5a4 = 0x02b79ab0

0x1138f5a0 = 0x06b21d04

0x1138f59c = 0x06b22034

0x1138f598 = 0x06b22014

<no data>

0x1138f594 = 0x02b79ab0

1138f5e4 660808ac System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext, System.AsyncCallback, System.Object)

PARAMETERS:

this = <no data>

context = <no data>

cb = <no data>

extraData = <no data>

LOCALS:

<no data>

1138f600 66083e1c System.Web.HttpRuntime.ProcessRequestInternal(System.Web.HttpWorkerRequest)

PARAMETERS:

this = 0x02aa1354

wr = 0x06b21418

LOCALS:

0x1138f600 = 0x06b21d04

<no data>

<no data>

<no data>

<no data>

1138f634 66083ac3 System.Web.HttpRuntime.ProcessRequestNoDemand(System.Web.HttpWorkerRequest)

PARAMETERS:

wr = <no data>

LOCALS:

<no data>

1138f644 66082c5c System.Web.Hosting.ISAPIRuntime.ProcessRequest(IntPtr, Int32)

PARAMETERS:

this = 0x02b5e0e4

ecb = <no data>

iWRType = <no data>

LOCALS:

0x1138f688 = 0x01fe3d08

0x1138f67c = 0x06b21418

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

1138f858 79f68c4e [ContextTransitionFrame: 1138f858]

1138f88c 79f68c4e [GCFrame: 1138f88c]

1138f9e8 79f68c4e [ComMethodFrame: 1138f9e8]

6、分析调用栈的参数和临时变量,从上面看到TestException.Page_Load有3个临时变量,其中后两个是空引用,虽然看不到这三个临时变量的变量名(不可能能看到),但根据代码可以推断出后面两个参数其中之一是handleResult的返回值,所以问题就在这儿。我们可以打印出第一个参数来看这个参数是不是我们所期望的,结果打印出来的值是个奇数,问题就确认了,到时候再来看客户为什么输入奇数就行了。

0:022> !do 0x06b243d4

Name: System.String

MethodTable: 793308ec

EEClass: 790ed64c

Size: 20(0x14) bytes

(C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)

String: 1

Fields:

MT Field Offset Type VT Attr Value Name

79332b38 4000096 4 System.Int32 1 instance 2 m_arrayLength

79332b38 4000097 8 System.Int32 1 instance 1 m_stringLength

793315cc 4000098 c System.Char 1 instance 31 m_firstChar

793308ec 4000099 10 System.String 0 shared static Empty

>> Domain:Value 000ce120:02a301d0 000fc948:02a301d0 0017ac48:02a301d0 <<

7933151c 400009a 14 System.Char[] 0 shared static WhitespaceChars

>> Domain:Value 000ce120:02a30728 000fc948:06a30bd4 0017ac48:06a87b80 <<

7、保存转储文件

.dump /f /o c:\temp.dmp

后续:如果只为了捕获异常,可以设置windbg的配置文件来让出现某些异常的时候自动调试,还可以用gflag或者手工修改注册表让某个应用崩溃的时候自动抓取Dump,本文是另一种思路,用设置断点的方式来排查问题。

关于windbg的使用,可以参考如下链接

【蛙蛙推荐】windbg使用小总结

或者熊力的《windows用户态程序高效排错》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: