2011-04-11 79 views
2

在我的C#應用​​程序中,我使用stacktrace來捕獲方法名稱和文件名以防失敗。stacktrace優化

x86和x64平臺之間的堆棧跟蹤有一些區別。

public string ErrorMessage 
    { 
     set 
     { 
     _strErrorMessage = "Error : " + value; 
     //Call the method to log error. 
     LogError(value); 
     } 
    } 

在上面的代碼片段中,在設置ErrorMessage屬性,我打電話的LOGERROR方法,這是捕獲堆棧跟蹤,並將其寫入日誌文件。

MethodA() 
{ 
    Logger obj=new Logger(); 
    obj.ErrorMessage="Failure"; 
} 

在這種情況下,在x86平臺上,堆棧跟蹤包含兩個堆棧幀。一個用於methodA,另一個用於ErrorMessage屬性的setter。

在x64平臺上,堆棧跟蹤僅包含methodA的一個堆棧幀,並且ErrorMessage屬性的設置者沒有堆棧幀。

任何人都可以向我解釋如何在獲取堆棧跟蹤時進行優化嗎?

+0

凡'MethodA'獲取調用?此代碼不完整。 – 2011-04-11 09:11:05

+0

交叉發表:http://social.msdn.microsoft.com/Forums/en/csharplanguage/thread/6aa690fc-d2f4-4d04-9dca-cf9d5a445724 – 2011-04-11 09:11:48

回答

2

當我嘗試在測試工具中獲取堆棧跟蹤輸出時,我看不到x64和x86輸出之間的任何區別。 (我並不期待,但我總是想挑戰我的假設!)。

我期望在調用堆棧中看到不同的唯一時間是當您編譯版本模式中的代碼時。當你這樣做時,JITter通常會簡單地進行簡單的方法調用,例如,你的財產的制定者。 (是的,如果你反思你的發佈模式代碼,你仍然看到單獨的方法;只有當方法被打出,你會看到這種差異)

這對你意味着什麼,調試,二傳手將出現在調用堆棧:

at ConsoleApplication5.Program.set_ErrorMessage(String value) 
    at ConsoleApplication5.Program.MethodA() 
    at ConsoleApplication5.Program.Main(String[] args) 

但是,當你在發佈模式下編譯它,內set_ErrorMessage的代碼將在內襯爲治法,也就是說,您只能看到這一點:

at ConsoleApplication5.Program.MethodA() 
    at ConsoleApplication5.Program.Main(String[] args) 

Th可以在Build選項卡的項目屬性中配置優化。當您在配置下拉菜單中切換調試和發佈時,您會看到「優化代碼」複選框的區別。是的,您可以關閉發佈版本的編譯器優化,但是那樣會妨礙應用程序的性能,我不建議這樣做。

1

我懷疑在x64上JIT更積極地內聯(優化)。試着做以下,看看是否是這樣的話,或只是在調試模式,在優化,影響調試應關閉運行:

public string ErrorMessage 
    { 
     [MethodImplAttribute(MethodImplOptions.NoInlining)] 
     set 
     { 
     _strErrorMessage = "Error : " + value; 
     //Call the method to log error. 
     LogError(value); 
     } 
    } 
+0

是的,這似乎是一個合理的理論。 64位JITter通常不同於32位JITter,直到決定是否內聯方法調用。 – 2011-04-11 10:07:26