4

几天前,我在工作中遇到了这个问题,我想知道有没有办法从场景中提取更多数据而不是去微软。有很多这样的案例,我想探索作为一个 Windows 开发人员,获取大部分信息的最佳/最佳方式是这种情况。我将描述情况:

  1. Office 应用程序在使用某些设置(涉及 cmyk 颜色空间)打印时会引发一个对话框错误,该对话框的描述错误。“文件 %s 无法打开,因为它已被其他应用程序锁定”。它不提供文件名,事件查看器也不提供。打印中止。

  2. 在使用时,当涉及的进程(如办公应用程序、假脱机程序、splwow64.exe (是的,它是 64 位系统,应用程序是 32 位)调用procmonapi 时,我们在多个文件上发现“文件锁定错误” )。CreatefileMapping

  3. 当不涉及 splwow64 时问题不存在,这意味着在 64 位操作系统上使用 64 位应用程序。

我想知道在这种情况下哪些工具有助于获取更多信息。这包括在需要时将 MS 符号与 windbg 和调试程序集一起使用。基本上我需要锁定的文件名,显示为 %s 和问题的根源。

4

1 回答 1

5

没有源代码和没有符号的调试很困难。所采取的方法因您可以观察到的内容和可以做出的假设而有很大差异。以下听起来对您的情况是合理的。

区分 64 位文件访问与 32 位版本

由于 64 位版本有效,请查看文件访问的不同之处。您可以将 Process Monitor 日志导出为 CSV,并编写一个分析文件访问的工具。您的分析工具可能应该

  • 将具有不同偏移量的多个文件读取访问汇总为整个文件的单个文件访问。
  • 忽略读取顺序,因为顺序似乎不太重要。
  • 首先忽略 DLL

也许你甚至可以在 Excel 本身中做到这一点。

捕获文件访问调用

首先,我认为使用 Process Monitor 已经是一个很好的方法。你在不知道任何事情的情况下发现应用程序正在做什么,所以这将是我的第一选择。

当然,很难缩小有问题的文件列表。如有必要,您需要检查所有这些,例如借助批处理文件并找到一个命令行工具,该工具可以帮助找到打开文件的应用程序。在这种情况下,请查看SysInternals Handle。它是一个命令行实用程序,您可以给它一个文件名。基本上,它是 Process Explorer 的命令行版本(见下文)。

读取文件和写入文件通常是通过 API 调用完成的,因此API Monitor是另一种选择。过滤所有可疑的文件访问方法(ReadFile、ReadFileEx、LockFile、LockFileEx、WriteFile、WriteFileEx,...)。

这也可以在 WinDbg 中通过设置断点来实现,但您可能会经常遇到它们,因此处理它们可能需要一些自动化。您可以为命令指定命令字符串bp

走运

可能会发生打算用作%s格式字符串参数的文件名位于内存中的某个位置。

  1. 在应用程序显示消息时进行故障转储
  2. 使用SysInternals Strings实用程序转储转储的所有字符串。
  3. 通过将其传递到命令直接过滤输出等,C:\或将其重定向到文本文件以供以后分析D:\find

这仍然会给您留下很多文件,因此找到罪魁祸首并不比使用以前的方法容易得多。同样,使用其他工具缩小列表范围,例如handle.

  1. 在应用程序显示消息时进行故障转储
  2. 在 WinDbg 中打开转储
  3. 转储您在堆栈上找到的某些地址的字符串。由于 NTFS 中的文件名是 Unicode,du <address>因此在这里应该可以正常工作。

这肯定需要更多关于内部知识的知识,例如在哪里可以找到好的指针等。

分析第一次机会异常

如果应用程序依赖于异常,您可能会通过检查第一次机会异常来获得一些见解。但是,如果应用程序进行了良好的先决条件检查,异常就会减少,从而降低您获取有用信息的机会。

如果情况重现良好,您可以

  1. 使用Image File Execution Options将 WinDbg 设置为该进程的调试器。
  2. 打开一个日志文件.logopen /t /u c:\firstchanceexceptions.log
  3. 让所有异常都使用sxe -c ".exr -1;k;g" *. 该g命令将立即继续,以便应用程序(希望)不会遇到超时。
  4. 继续执行g
  5. 当应用程序终止时,关闭日志文件.logclose
  6. 查看日志文件以获取有趣的异常/有趣的调用堆栈
  7. 重现错误,但这次停止有趣的异常
  8. 查看方法参数和内存是否找到文件名(再次使用du <address>

查找属于消息框的应用程序

如果您无法确定哪个应用程序显示错误消息,例如由于消息标题错误,请执行以下操作:

  1. 下载SysInternals Process Explorer并运行它。

  2. 将工具栏中的十字准线拖到窗口上方。

  3. Process Explorer 现在突出显示拥有该窗口的可执行文件

如果打印了文件名,则查找锁定应用程序

如果对话框显示文件名而不仅仅是“%s”:

  1. 也使用进程资源管理器

  2. 使用查找/查找句柄或 DLL 或按Ctrl+F

  3. 键入文件名或文件名的一部分

于 2014-06-01T20:58:18.373 回答