原文地址: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()
好了,一切都好極了,但那僅僅解釋了堆棧溢出。那麼瘋狂的循環是怎麼回事呢?
好...想象一下有這樣一個函數(在-->處有有一個斷點)