无法让 xperfview 加载 DLL 的符号

Posted

技术标签:

【中文标题】无法让 xperfview 加载 DLL 的符号【英文标题】:Trouble getting xperfview to load symbols for DLL 【发布时间】:2011-12-21 21:34:19 【问题描述】:

我一直在努力使用 xperf 来获取我正在分析的工具的符号。我在该工具中运行的代码在 .exe 和 .dll 之间进行了拆分——要分析的重要内容位于 .dll 中。我跑了 xperf:

xperf -on PROC_THREAD+LOADER+INTERRUPT+DPC+PROFILE -stackwalk profile

然后我运行我的工具一会儿,然后

xperf -d profile.etl

然后我尝试了 xperfview。我加载了配置文件,打开了“加载符号”,然后打开了汇总表。根本没有符号——从字面上看,模块在函数列中出现了“未知”。我已经搜索了其他线程,这就是我尝试过的:

    我设置了我的环境变量 _NT_SYMBOL_PATH 和 _NT_SYMCACHE 我清除了符号缓存并运行 xperf -symbols -i profile_results.etl。 我从最新版本的 Windows 调试工具中复制了 dbghelp.dll 并重复了上述操作。

完成所有这些操作后,我现在可以正确显示大多数模块的函数名称,这些模块不是我自己的代码,但我无法显示我的 dll。 dll 在发布模式下编译(经过优化),但我将 Visual Studio 项目专门设置为创建 pdb,我已验证 pdb 存在并且它位于我的 _NT_SYMBOL_PATH 上的目录中。有谁知道我该如何解决这个问题,或者至少进一步调试它?

【问题讨论】:

你有解决这个问题的办法吗?似乎它遍布互联网,但没有指导如何解决这个问题 很遗憾,没有。我从来没有得到这个工作。我辞掉了为此工作的工作,并加入了一家使用 Python 开发分布式后端的初创公司。这是光荣的。然后我们被雅虎收购了。无论如何,问题仍未解决。 【参考方案1】:

您可以set some environment variables 在符号加载期间启用诊断日志记录:

DBGHELP_DBGOUT = 1 DBGHELP_LOG = C:\dbghelp.log

【讨论】:

【参考方案2】:

我刚遇到同样的问题...尝试了所有相同的步骤...浏览了所有(显然)类似的建议...

此外,我尝试使用复制到 WPA 'bin' 文件夹中的相同 dbghelp.dll/symsrv.dll DLL 启动 symchk,以确保我的 PDB 是可定位的。 (还在想我要疯了……)

我应该注意:我的 _NT_SYMBOL_PATH 值包含具有 lcl 缓存和直接本地位置的服务器:_NT_SYMBOL_PATH=srv*D:\SymbolCache*http://msdl.microsoft.com/download/symbols;D:\GitHub\...

然后我恍然大悟,我的“合作伙伴”EXE 使用的 DLL 是通过 LoadLibrary()/GetProcAddress()动态加载的...这可能是 XPerf 的问题吗? ???

我什至犹豫了一下...

我在我的 DLL 中添加了一个无用的导出,并直接在 EXE 中调用它(为我的 DLL 触发一个导入表条目)所以现在 EXE 依赖 DLL 甚至加载。

原来...

......然后 XPerf 加载了所有符号:)。

编辑:我刚刚在 MSDN 上找到了这个 URL,有人在 11 年发布了代码,展示了类似(相同?)的问题

编辑

我最近与一位同事讨论了这个问题,并了解到 XPerf 将正确“决定”为以编程方式加载的 DLL 加载符号...如果 DLL 会一直加载到进程终止。

因此,对于在执行期间加载和卸载以及在终止时卸载的 DLL...XPerf 将跳过加载这些符号的尝试。

【讨论】:

【参考方案3】:

我不确定这是否有帮助,但除了xperf can't load my DLL's symbols 的问答之外,这里还有我今天遇到的另一个细节:

对我来说,xperfview 不喜欢映射网络驱动器上的 PDB 文件:因为我在构建代码的不同机器上运行 xperf 和 xperfview,我从网络共享中获取可执行文件和 PDB 文件,这我映射到一个驱动器号以重新创建与构建机器上完全相同的绝对路径 - 不走运。即使将带有 PDB 文件的文件夹添加到符号路径也无济于事。

一旦我确定 .pdb 文件位于本地文件夹中,一切都会按预期进行。

【讨论】:

【参考方案4】:

尝试使用 wpa 而不是 xperfview。它使用与 xperfview 相同的系统来加载符号,但它还有一个诊断控制台,可让您查看有用的符号加载消息。

另外,您应该告诉我们您将 _NT_SYMBOL_PATH 设置为什么。设置错误的方式有很多。

此外,在 _NT_SYMBOL_PATH 中,您应该为您的 PDB 文件指定一个本地缓存 - 然后您可以在那里检查您的 PDB 是否已复制到本地缓存。

您还可以查看存储 WPT .symcache 文件的 SymCache 路径(由 _NT_SYMCACHE_PATH 指向,默认为 c:\symcache)。 PDB 文件被转换为这种格式,而 .symcache 文件最终由 WPA 和 xperfview 加载。

欲了解更多信息,请参阅:

http://randomascii.wordpress.com/2012/10/04/xperf-symbol-loading-pitfalls/

【讨论】:

以上是关于无法让 xperfview 加载 DLL 的符号的主要内容,如果未能解决你的问题,请参考以下文章

不会为 slc.dll 和 sppc.dll 加载调试符号

据说调试符号不会为文档加载,即使它们是为 dll 加载的

从应用程序中获取显式加载的 DLL 的符号

阻止 Visual Studio 尝试为特定 DLL 加载符号

VS2013编译经常卡在正在从以下位置加载xxx.dll的符号

无法加载 DLL 'opencv_core242':找不到指定的模块。恩古简历