【问题标题】:How to drill down to code who created the handle如何深入查看创建句柄的代码
【发布时间】:2015-02-10 12:26:38
【问题描述】:

我知道如果我们提供 Handle.exe 的绝对路径,它将列出锁定文件的所有进程。

F:\Softwares\Handle>Handle.exe  D:\Source\sample.dll

Handle v4.0
Copyright (C) 1997-2014 Mark Russinovich
Sysinternals - www.sysinternals.com

test1.exe           pid: 9928   type: File           408: D:\Source\sample.dll
test2.exe           pid: 10840  type: File           6A8: D:\Source\sample.dll
test3.exe           pid: 15788  type: File           374: D:\Source\sample.dll
test4.exe           pid: 10940  type: File           308: D:\Source\sample.dll
test5.exe           pid: 15424  type: File           3FC: D:\Source\sample.dll
test6.exe           pid: 10076  type: File           8AC: D:\Source\sample.dll

Windows 7 64 位

正如 Handle.exe 所述,我的 sample.dll 被 6 个不同的进程锁定。 我想知道哪一行代码实际上保存了每个进程的 sample.dll。 我的任务是修复我庞大的应用程序中的句柄泄漏。所以我的问题并没有固定到程序的特定部分。 任务是我必须生成包含句柄泄漏诊断谁创建它的报告。 泄漏并非特定于文件,它扩展到所有系统资源,如文件、注册表项、事件、信号量、线程...等。

我已经使用 windbg 进行了转储,但我找不到如何诊断转储文件,尤其是针对句柄泄漏。在我大约半天的搜索中,找不到适合我的问题的好的教程或解决方案。

是否有任何命令行工具或任何其他工具可以回答我的问题。

【问题讨论】:

  • 在没有可读调试信息 (PDB) 的已编译应用程序中,这是不可能的。代码行和它在编译时生成的汇编语句之间没有固定的关系,因此通常不可能将语句追溯到高级代码。使用完全解释的语言和一些混合解释器运行时,这可能是可能的,但这远非普遍。
  • 此外,即使有可能。理论上它可以是任意数量的行。你到底想解决什么问题?
  • @Ramhound 在我上面的示例中 D:\Source\Sample.dll 被 6 个进程锁定。在我的应用程序中,这是由某些部分代码加载的,并且没有正确发布。有类似的问题,如句柄泄漏、文件、注册表项、事件...等。我的问题是代码的哪一部分锁定了手柄?我想要一个实用的解决方案
  • 通常,DLL 加载是在程序代码之外处理的。您只需包含一个 dll,编译器和加载器会负责其余的工作。对于(非dll)外部资源泄漏,正确实现try-finally结构,保证即使发生crash也能释放资源。短期锁定发生在读取时,而长期锁定发生在打开文件进行写入或主动写入时。
  • @Srikanth - 每次从 dll 加载符号然后调用该代码时,您都会创建对 dll 的依赖项。你有这些进程的调试信息吗?

标签: windows-7 sysinternals handle


【解决方案1】:

您使用了错误的调试工具。您想阅读this article,它详细介绍了如何使用!htrace 调试器命令获取泄漏句柄的堆栈跟踪。 this existing SO 问题也涵盖了这一点。

您会看到经常提到的“Windows 调试工具”。它不再是单独下载,而是包含在 Windows SDK 安装中。

【讨论】:

  • 谢谢你我更新了我的帖子,也正如你所建议的,我已经在使用 windbg,但我不知道如何使用 windbg 进入代码级别。由于 windbg 的结果始终是内核中对象引用表的内存位置。
【解决方案2】:

我认为您可以使用procmon,另一个Sysinternals 工具找到罪魁祸首。

这会让你很开心,唯一的问题是句柄创建速度非常慢 - 你不能记录系统活动超过十分之几分钟...除非你的系统安装了大量内存。

一旦你记录了你的事件(不要忘记以管理员身份运行它,并在几分钟后停止它,我更喜欢在通常停止它后分析捕获的数据)进入菜单“工具”->“文件摘要”并在那里找到访问的文件。

双击文件(或目录、文件夹视图等...双击“anywehere”),将在 procmon 视图中添加一个过滤器,让您分析有关它的每一个操作,执行由系统中运行的任何进程。

如果您双击单个操作,您还可以在该系统调用的上下文中查看堆栈的回溯,以及有关 I/O(在此特定情况下)操作的更多详细信息。

【讨论】:

  • 您可以设置过滤器和“删除过滤事件”以允许 procmon 运行更长的时间而不会达到内存限制。
猜你喜欢
  • 2016-01-12
  • 2020-07-19
  • 1970-01-01
  • 2014-02-21
  • 1970-01-01
  • 2010-11-23
  • 1970-01-01
  • 1970-01-01
  • 2021-07-01
相关资源
最近更新 更多