分享
 
 
 

ASP.NET 崩溃-SiteMap中疯狂的循环

王朝asp·作者佚名  2008-05-30
窄屏简体版  字體: |||超大  

原文地址:http://blogs.msdn.com/tess/archive/2006/10/10/ASP.NET-Crash-_2D00_-Crazy-looping-in-a-SiteMap.aspx

发布时间:Tuesday, October 10, 2006 4:10 PM

作者:Tess

一天,我收到了一封有关我的博客的邮件,提出如下问题,简述如下:

我想快速地创建一个站点地图,因此我重写了BuildSiteMap()方法,在里面我写了一个循环,用以添加一些仿造的sitemap节点。

public override SiteMapNode BuildSiteMap(){

for (int i = 0; i < 5; i++)

myRoot.ChildNodes.Add(new SiteMapNode(this, i.ToString(), i.ToString(), i.ToString()));

return myRoot;

}

运行程序,就发生堆栈溢出,服务器也崩溃了。我用调试器单步调试,发现真的很奇怪:

1) int i = 0

2) i < 5

3) myRoot...

4) int i = 0

5) i < 5

etc.

i的值看起来从来没有增加,除非我调用到SiteMapNode(access a property, call a method),看起来这个循环是正确的。

是什么使得这个循环不确定呢?咋看可能是编译器或者是CLR的一个bug.

(当我获此问题时,我真不知道ASP.NET2.0中的站点导航,但我找到了这些文章... http://weblogs.asp.net/scottgu/archive/2005/11/20/431019.aspx 和http://aspnet.4guysfromrolla.com/articles/111605-1.aspx ,叙述得真是很不错.)

最初的想法

这个问题最重要的就是它始终重新开始, 这就意味着可以对此做现场调试。但我们暂不走那么远,先回头看看现在有什么...

1. 堆栈溢出

2. 一次又一次重新开始的循环

我已经在先前的博客帖子里讨论过堆栈溢出,现在重复一下... 引起堆栈溢出的原因是, 分配了太多的函数指针,变量指针和参数,以致在堆栈里申请的内存数量不够用。到目前为止,堆栈溢出最平常的原因是无终止的递归。换句话说,function A调用了function B, function B又调用了function A...

因此,callstack看上去有点像这样....

...

functionB()

functionA()

functionB()

functionA()

好了,一切都好极了,但那仅仅解释了堆栈溢出。那么疯狂的循环是怎么回事呢?

好...想象一下有这样一个函数(在-->处有有一个断点)

void MyRecursiveFunction(){

for(int i=0; i<5; i++){

--> MyRecursiveFunction();

}

}

当你第一次停在断点处,i的值应该是0,callstack看起来是这样的...

MyRecursiveFunction()

...

现在调用MyRecrusive函数,每一次调用这个函数自己,会再一次出现 i=0(虽然我们并不真的在同一个loop里)。若调用MyRecrusive这个函数几个来回,并用实际执行的代码代替之,它将执行类似如下的代码:

for(int i=0; i<5; i++){

for(int i2=0; i2<5; i2++){

for(int i3=0; i3<5; i3++){

for(int i4=0; i4<5; i4++){

for(int i5=0; i5<5; i5++){

for(int i6=0; i6<5; i6++){

for(int i7=0; i7<5; i7++){

...

}

}

}

}

}

}

}

... 在visual studio中查看它,看起来总是运行同样的循环,且并不改变变量i的值。暂时,你对此不会有深层次的理解,直到你真正看到堆栈调用。

假如我们看一下callstack, callstack现在看起来是这样的...

MyRecursiveFunction()

MyRecursiveFunction()

MyRecursiveFunction()

MyRecursiveFunction()

MyRecursiveFunction()

MyRecursiveFunction()

MyRecursiveFunction()

...

因此最初想法的结论是,我们无疑地要看看某些递归...但在哪呢?例子中的代码

myRoot.ChildNodes.Add(new SiteMapNode(this, i.ToString(), i.ToString(), i.ToString()));

看起来并不是那么复杂...

在这儿最可疑的是new SiteMapNode() 和myRoot.ChildNodes.Add() ,假如我们用reflector查看一下,那么这将不再那么神秘。

调试问题

最后:) 少一点口舌,多来一点windbg行动...

因它易重新呈现,所以我会在我的机器上重新呈现它,我只要将windbg (File / Attach to process)附到w3wp.exe上,点击g开始即可。然后会重新产生了这个问题,程序中止时提示我这是一个堆栈溢出(我们已经知道了)。

(7e4.ddc): Stack overflow - code c00000fd (first chance)

First chance exceptions are reported before any exception handling.

This exception may be expected and handled.

eax=0fa4235c ebx=02beca74 ecx=02beca74 edx=02becb54 esi=02becb54 edi=02beca74

eip=686b5cb4 esp=02163000 ebp=02163004 iopl=0 nv up ei pl zr na pe nc

cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00210246

System_Web_ni+0xf5cb4:686b5cb4 56 push esi

我们查看一下堆栈,使用 !clrstack命令看看是怎么中止的,但我们只能看到....

0:016> !clrstack

OS Thread Id: 0xddc (16)

ESP EIP 02163000 686b5cb4 System.Web.StaticSiteMapProvider.GetChildNodes(System.Web.SiteMapNode)

... 这对我们并没有太大的帮助。有时当我们遇到堆栈溢出时,使用!clrstack 命令就会出现一些这样的问题。因此我们还需要使用!dumpstack命令查看一下raw stack。

0:016> !dumpstack

OS Thread Id: 0xddc (16)

Current frame: (MethodDesc 0x68b03720 +0x4 System.Web.StaticSiteMapProvider.GetChildNodes(System.Web.SiteMapNode))

ChildEBP RetAddr Caller,Callee

02163004 686b1fc4 (MethodDesc 0x68aeff30 +0x18 System.Web.SiteMapNode.get_ChildNodes())

0216300c 0f765641 (MethodDesc 0xfa42328 +0x59 ViewSiteMapProvider.BuildSiteMap())

0216303c 686b5cdf (MethodDesc 0x68b03720 +0x2f System.Web.StaticSiteMapProvider.GetChildNodes(System.Web.SiteMapNode))

02163074 686b1fc4 (MethodDesc 0x68aeff30 +0x18 System.Web.SiteMapNode.get_ChildNodes())

0216307c 0f765641 (MethodDesc 0xfa42328 +0x59 ViewSiteMapProvider.BuildSiteMap())

021630ac 686b5cdf (MethodDesc 0x68b03720 +0x2f System.Web.StaticSiteMapProvider.GetChildNodes(System.Web.SiteMapNode))

021630e4 686b1fc4 (MethodDesc 0x68aeff30 +0x18 System.Web.SiteMapNode.get_ChildNodes())

021630ec 0f765641 (MethodDesc 0xfa42328 +0x59 ViewSiteMapProvider.BuildSiteMap())

0216311c 686b5cdf (MethodDesc 0x68b03720 +0x2f System.Web.StaticSiteMapProvider.GetChildNodes(System.Web.SiteMapNode))

02163154 686b1fc4 (MethodDesc 0x68aeff30 +0x18 System.Web.SiteMapNode.get_ChildNodes())

0216315c 0f765641 (MethodDesc 0xfa42328 +0x59 ViewSiteMapProvider.BuildSiteMap())

...

好了,这看起来问题出自ChildNodes属性。使用该属性时,会调用GetChildNodes 函数,这个函数会再次调用BuildSiteMap 函数,从而它又调用了ChildNodes 属性,如此一直下去,导致了堆栈溢出。

结论

在关于BuildSitemap的文档中,你能找到如下段落:

BuildSiteMap 方法由 FindSiteMapNode、GetChildNodes和GetParentNode方法的默认实现调用。如果在派生类中重写 BuildSiteMap 方法,请确保它仅加载一次站点地图数据,并在后续调用中返回。

为了避免出现递归和堆栈溢出,最好避免调用该方法,像在BuildSiteMap例子里,我们可以用AddNode方法来添加子节点。

这在归档在Site Map Providers这篇文章中,该文同样值得一读。

BuildSiteMap 一般不应当调用其他的site map提供的方法或属性,因为许多方法和属性默认会实现BuildSiteMap调用。 例如,BuildSiteMap中的RootNode会引起递归,从而使之以堆栈溢出而终止。

http://www.cnblogs.com/Ring1981/archive/2006/10/19/443280.html

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有