2

我在使用 xperf 跟踪获取完整调用堆栈时遇到了一些问题。这是在 Win7 64 位电脑上。在更高的层次上,我有一个加载多个 dll 的 exe,这些 dll 也完成了大部分工作。所有 pdb 文件都在一个目录中,并且我在可执行代码中获得了有效符号和调用堆栈,所以我很确定我的符号路径设置正确。

一旦我的 exe 调用其中一个加载的 dll,我就会丢失调用堆栈信息,并且堆栈列显示 plugin_name.dll!?,当展开时,它会调用自身。权重选项卡显示高百分比(50-90%)和高计数,但我无法获得堆栈的任何实际函数调用。例如:

Process, Stack, Module, Function, Weight, % Weight, Count, TimeStamp
,    |     kernel32.dll!BaseThreadInitThunk, , , 59067.075556, 73.29, 59075, 
,    |     |- plugin_name.dll!?, , , 45036.186642, 55.88, 45042, 
,    |     |     plugin_name.dll!?, , , 45036.186642, 55.88, 45042, 

基于这些,

http://blogs.msdn.com/b/pigscanfly/archive/2009/08/06/stack-walking-in-xperf.aspx http://msdn.microsoft.com/en-us/library/windows/desktop /ff191014(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/ff191014.aspx

这似乎表明 xperf

  • “...不知道地址处的可执行映像是什么”
  • “...超过最大堆栈深度”

我发现的可能原因是 FPO(帧指针优化)已打开(我已用 /Oy 明确禁用,即使它们不应该打开),或者超出了最大堆栈深度,我不确定如何确定这是否是我要击中的。

由于无法查看在 dll 中花费的时间,我无法获得非常有用的信息,所以我想弄清楚发生了什么。

有人对阅读或尝试的东西有任何建议吗?我缺少的 stackwalk 是否有任何限制?符号是否有任何特殊设置,特定于 dll 中的调用堆栈?

4

3 回答 3

2

大多数符号加载问题是由于调试引擎和符号服务器库不匹配而发生的。

安装包含 Windows 性能套件的最新 sdk 并从同一目录运行 wpa/xperf 应该可以解决符号加载问题。我假设符号服务器路径是正确的。使用 procexp.exe 查看 dbghelp.dll 和 symsrv.dll 版本以及查看 xperf 的路径或目录中的任何工具都指向上述 dll 的最新可用或已发布版本。

谢谢, SushantB

于 2018-08-08T11:58:37.840 回答
0

创建一个新的环境变量 DBGHELP,将其设置为1。现在创建一个环境变量 DBGHELP_LOG并将其设置为像D:\DbgHelpLog.txt这样的日志文件。符号加载完成后,关闭 xperfview/wpa 并查看日志为什么符号加载失败。

诊断 DBGHELP 符号加载

http://blogs.msdn.com/b/matt_pietrek/archive/2005/04/12/407721.aspx

于 2013-08-06T09:09:31.410 回答
0

从这里尝试以下操作:禁用分页执行

为了在 64 位 Windows 上进行跟踪,您需要设置 DisablePagingExecutive 注册表项。这告诉操作系统不要将内核模式驱动程序和系统代码分页到磁盘,这是使用 xperf 获取 64 位调用堆栈的先决条件,因为 64 位堆栈遍历依赖于可执行映像中的元数据,并且在某些情况下xperf 堆栈遍历代码不允许触摸分页页面。从提升的命令提示符运行以下命令将为您设置此注册表项。

REG ADD "HKLM\System\CurrentControlSet\Control\Session Manager\Memory Management" -v DisablePagingExecutive -d 0x1 -t REG_DWORD -f

设置此注册表项后,您需要重新启动系统才能记录调用堆栈。设置此标志意味着 Windows 内核将更多页面锁定到 RAM 中,因此这可能会消耗大约 10 MB 的额外物理内存。

于 2012-10-23T11:04:32.460 回答