如何解决在Windows Server 2012 R2上针对64位进程使用PerfView时出现的BROKEN堆栈问题

8
我正在一个CPU占用率会突然飙升到100%几分钟的生产系统上运行perfview(默认采集)。我得到了一些有用的结果,但同时也得到了一堆“BROKEN STACKS”(破碎堆栈)。
该机器运行Windows Server 2012 R2。应用程序是一个被启动的exe文件。该应用程序编译为.NET 4.0版本,但服务器运行的是.NET 4.6.1版本。 perfview帮助文档说,在我的情况下,这些BROKEN STACKS已在Windows 8中得到修复(我猜想也适用于Windows Server 2012)。我的dll没有进行ngen操作,但我认为不需要这样做,因为这个问题在Windows 8中已经得到解决。
你有什么想法吗?

打开WPA中的ETL,加载符号并在此处扩展堆栈。https://channel9.msdn.com/Shows/Defrag-Tools/Defrag-Tools-42-WPT-CPU-Analysis 堆栈是否也被破坏了? - magicandre1981
有任何更新吗?你尝试过WPA了吗? - magicandre1981
我已经尝试过WPA了。它似乎有数据,但是使用起来比PerfView要困难得多。我还没有能够用它找到我的答案。 - Mark
不,我发现看到原因要容易得多且更快。 - magicandre1981
2个回答

4

来自PerfView命令行帮助:

用法:PerfView EnableKernelStacks

在X64机器上,如果您遇到内核中代码执行时堆栈损坏的问题,设置此选项并重新启动可能会改善情况。


0
根据PerfView文档:

跟踪中的“BROKEN”堆栈帧- 在数据收集期间,当事件触发时,会进行堆栈跟踪。当此跟踪不完整时,称为损坏的堆栈,并且可能由多种原因引起。

我们还可以了解到以下原因,为什么会有一些损坏的堆栈:

破碎的堆栈出现的原因如下: 1.在32位进程中,ETW依赖于编译器通过发出“EBP Frame”来标记堆栈。当它未能完全执行此操作并使用EBP寄存器进行其他用途时,它会破坏堆栈。这不应该发生在操作系统代码或.NET Runtime代码中,但可能会发生在第三方代码中。 2.在64位Windows 7或Windows Server 2008上的32位进程中存在一个错误,其中某些会话中统一丢弃堆栈。好消息是它只是间歇性地发生。因此,如果您再次收集数据,则很可能会避开此错误。这应该在Windows 8中修复。 3.在64位进程中,ETW依赖于不同的机制来遍历堆栈。在此机制中,编译器生成“展开信息”。目前,此ETW机制对动态生成的代码(由.NET runtime JIT编译器生成)无法正常工作。这会导致堆栈在堆栈上的第一个JIT编译方法处中断(您可以看到JIT编译方法,但没有调用该方法的调用者)。这个问题在Window8上得到了解决,但在之前的操作系统版本中没有解决。 4.异步活动。堆栈爬行是一项“尽力而为”的服务。如果在采样时无法安全地进行日志记录,则操作系统会简单地跳过它。例如,如果在内核中爬行堆栈时发现堆栈页面已交换到磁盘上,则堆栈爬行将被简单地中止。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接