2011-04-11 48 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