在我的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的堆栈框架。
有人可以向我解释在获取堆栈跟踪时如何进行优化吗?
答案 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);
}
}