2013-03-12 51 views
6

我用下面的方法在我的ASP.NET Web應用程序接收堆棧跟蹤異常返回預期的信息:堆棧跟蹤/的StackFrame不要在生產環境中

public static void getStackTraceInfo(System.Diagnostics.StackTrace trace) 
{ 
    for (int i = 0; i < trace.FrameCount; i++) 
    { 
     int nLine = trace.GetFrame(i).GetFileLineNumber(); 
     int nCol = trace.GetFrame(i).GetFileColumnNumber(); 
     string methodName = trace.GetFrame(i).GetMethod().Name; 
    } 
} 

try 
{ 
} 
catch(Exception ex) 
{ 
    getStackTraceInfo(new System.Diagnostics.StackTrace(ex, true)); 
} 

它給我全系列/列/方法名稱信息,如果我在Visual Studio 2010開發環境中運行它,但是在IIS上的生產環境中,它將返回所有0,並將方法名稱作爲空字符串。

我是否需要做任何特殊的事情來使它在IIS上工作?

+0

我編輯了你的標題。請參閱:「[應該在其標題中包含」標籤「](http://meta.stackexchange.com/questions/19190/)」,其中的共識是「不,他們不應該」。 – 2013-03-12 17:45:11

+1

這是正確的。除非應用程序在調試模式下編譯並且相關的.pdb文件放置在生產中的bin目錄中,否則不會獲得具有完整調試信息(包括行號)的堆棧跟蹤。不是推薦的做法。 – 2013-03-12 17:47:28

+0

如果你的代碼在「build」中的「release」模式下,我想你不會得到行號。 – dekdev 2013-03-12 17:48:15

回答

29

如果我在Visual Studio 2010開發環境中運行它,它將爲我提供完整的行/列/方法名稱信息,但在IIS上的生產環境中,它會返回全0和方法名稱作爲空字符串。

正確。仔細閱讀該類型的名稱;那Diagnostics很重要。該名稱空間中的類型用於診斷調試環境中的問題。

我是否需要做任何特殊的事情來使它在IIS上工作?

否;您不需要使用診斷工具生產

如果由於某種原因想要在生產環境中使用診斷工具,至少需要將PDB文件推送到生產環境。這可能是一個危險而愚蠢的做法,我們將在下面看到。我建議你不要這麼做。

一些問題,你沒有問:

什麼工具我應該使用以獲得在生產環境中的來電者信息?

如果您需要獲取方法調用的行號等,您可能應該使用的工具是新的CallerLineNumber和C#5.0中的相關屬性。這裏有他們一個很好的博客:

http://blog.slaks.net/2011/10/subtleties-of-c-5s-new-callerlinenumber.html

如果您需要獲得有關異常的堆棧跟蹤信息,你看到的是你會得到什麼。

在調試環境中確實堆棧跟蹤目標提供了保證,該堆棧跟蹤告訴我在當前呼叫從來的?

不是。一個堆棧跟蹤不會告訴你你從哪裏來的第一個地方。堆棧跟蹤告訴你你要去哪裏。這很有用,因爲你來自哪裏和你下一步要去哪裏往往有很強的相關性;通常你會回到你來自的地方。

雖然這並非總是如此。 CLR有時會知道下一步該怎麼走,而不知道你來自哪裏,在這種情況下堆棧跟蹤不包含所需的信息。

例如,尾調用優化可以從堆棧中刪除幀。內聯優化可以使方法調用看起來像調用方法的一部分。 C#5中的異步工作流完全離開「你從哪裏來」和「你下一步要去哪裏」;異步方法的堆棧跟蹤在await告訴你你要去的是下一個await之後繼續,而不是你在第一個await之前如何進入該方法。

堆棧痕跡不可靠,所以不要依賴它們。僅將它們用作診斷輔助工具。

爲什麼在ASP中暴露診斷信息特別危險?

因爲攻擊者會通過拋出「異常」輸入來引起服務器故障。如果這使服務器失效,那麼攻擊者會很高興。如果它使服務器保持運行狀態,但會向攻擊者泄露有關您的源代碼的信息,甚至更好。現在他們有更多的信息可用來發起更復雜的攻擊。

ASP服務器應該在生產環境中儘可能少地提供診斷信息。您在該生產環境中擁有的調試信息越少,您犯錯誤的可能性就越小,並將實施細節公開給攻擊者。

+0

好點,除了這句話'堆棧跟蹤不會告訴你你從哪裏來'。它完全告訴你。當然,有些程序可能會對其進行修改,但這對於磨機代碼的運行來說太不尋常了。至於將所有這些調試器信息暴露給公衆的危險 - 我完全同意。所有這些信息進入一個內部日誌,不會被公開。 – ahmd0 2013-03-12 18:10:46

+17

@ ahmd0:當我告訴人們堆棧跟蹤的真相時,我感到驚訝。堆棧跟蹤包含*返回地址*,該地址不一定是*調用方*的地址。大部分時間都是這樣,但不一定是這樣,有些情況並非如此。請記住,堆棧的目的是*繼續*的具體化,並且延續是關於*未來*,而不是過去*的定義信息。如果你有時可以從延續中推斷關於過去的信息,那很好,但這不是它的目的*,所以你不能依賴它。 – 2013-03-12 18:17:11

+2

當然也沒有要求繼續由堆棧來完成。正如我上面提到的,異步任務的繼續由委託和上下文的組合來表示,沒有涉及到堆棧,因此瞭解任務的繼續並不能告訴你任務是如何開始的。 – 2013-03-12 18:18:43