ASP.NET 崩溃SiteMap中疯狂的循环(2)
因此最初想法的结论是,我们无疑地要看看某些递归...但在哪呢?例子中的代码
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开始即可。然后会重新产生了这个问题,程序中止时提示我这是一个堆栈溢出(我们已经知道了)。(来源 www.iocblog.net)
(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
Tag: SiteMap
文章整理:iocblog
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。