堆栈跟踪优化

时间:2011-04-11 08:48:06

标签: c# .net wpf 64-bit stack-trace

在我的C#应用​​程序中,我使用了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属性的setter的堆栈框架。

有人可以向我解释在获取堆栈跟踪时如何进行优化吗?

2 个答案:

答案 0 :(得分:2)

当我尝试在测试工具中获取堆栈跟踪输出时,我发现x64和x86输出之间没有任何区别。 (我没想到,但我总是想挑战我的假设!)。

我唯一希望在调用堆栈中看到差异的时候是在发布模式下编译代码。执行此操作时,JITter通常会插入简单的方法调用,例如:你的财产的制定者。 (是的,如果你反思你的发布模式代码,你 仍然会看到单独的方法;只有当方法被JIT时,你才能看到这种差异)

这对您来说意味着在调试中,setter将出现在调用堆栈中:

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

但是当你在发布模式下编译它时,set_ErrorMessage中的代码将被内嵌到MethodA中,这意味着你只会看到这个:

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

此优化可在“构建”选项卡上的项目属性中进行配置。当您在配置下拉菜单中的调试和发布之间切换时,您会在“优化代码”复选框中看到差异。是的,您可以关闭发布版本的编译器优化,但是您可能会妨碍应用程序的性能,我不建议这样做。

答案 1 :(得分:1)

我怀疑在x64上JIT正在更积极地内联(优化)。尝试执行以下操作以查看是否是这种情况,或者只是在调试模式下运行,其中应该关闭影响调试的优化:

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