1

我正在尝试帮助客户解决问题,但我的想法已经不多了。他们有一个自定义的、内部编写的应用程序,该应用程序按计划运行,但它崩溃了。我不知道这种情况已经有多久了,所以我认为我无法将崩溃追溯到任何特定的软件更新。最不幸的部分是不再有任何包含逻辑内容的 VB6 DLL 源代码。

这个 VB6 DLL 由 VB 脚本的 2-3 个函数调用启动。显然,我可以修改 VB 脚本以添加错误日志记录,但我无法获得质量信息来查明崩溃的根源。我已将日志消息放在所有函数调用的任一侧,并确定哪些调用导致了崩溃。但是,err 对象中不会返回任何内容,因为调用正在使 wscript.exe 崩溃。

我不确定我还能做些什么。有任何想法吗?

编辑:即使我没有源代码,我关心的主要原因是可能有一些外部因素导致崩溃(凭据不足、文件锁定等)。我检查了由于 wscript.exe 崩溃而在 drwtsn32.log 中创建的日志文件,我得到的唯一信息是“访问冲突”。

我首先倾向于认为这与安全权限有关,但这难道不是内存访问违规吗?

4

10 回答 10

6

如果您确实认为这是文件权限等环境的问题,您可以考虑使用Sysinternals工具之一。我曾经使用 Filemon 来找出我的应用程序接触到的所有文件,并以这种方式发现了一个问题。

您可能还想使用Dependency Walker进行快速健全性检查,以确保您实际上正在加载您认为的 DLL 文件。我看到加载了错误版本的 C 运行时并导致了神秘的崩溃。

于 2009-01-13T17:05:10.640 回答
4

根据应用程序的范围,您的客户可能需要考虑重写。如果没有源代码,当其他事情发生变化时,他们最终将被迫这样做。

于 2009-01-13T15:57:20.123 回答
4

始终可以使用调试器(直接在运行崩溃应用程序的 PC 上或内存转储上)来或多或少地确定正在发生的事情。在这种情况下,代码是 VB6,这可能不是很有帮助,因为您只能在 Win32 级别获得有用的信息。

最终,如果您没有源代码,那么找出错误真正有帮助的地方是什么?除非您可以在调用脚本中永远避免该代码路径,否则您将无法修复它。

于 2009-01-13T16:01:27.743 回答
4

您可以使用windows 的调试工具。这可能会帮助您查明错误,但如果没有修复它的来源,对您没有多大好处。

一种更懒惰的方法是从代码(而不是脚本)调用 dll,这样您至少可以看到导致问题的原因并检查 err 对象。您仍然无法修复它,除非问题是它被错误地调用。

于 2009-01-13T16:04:23.790 回答
2

Coding The Wheel的人有一个非常有趣的系列,关于构建一个充满严肃技术信息的在线扑克机器人,其中很多都与如何进入现有应用程序并搞乱它们有关,在某种程度上,你想做什么。

具体来说,他有一篇关于使用 WinDbg 获取重要信息的文章,一篇关于如何将函数调用弯曲到您自己的代码以及一篇关于在其他进程中注入 DLL 的文章。这些技术可能有助于发现并可能解决或修复崩溃,尽管我想这仍然是一个艰难的决定。

于 2009-01-13T16:32:00.397 回答
2

有几个工具可能会有所帮助。首先,您可以使用dependency walker 对您的应用程序进行运行时配置文件:

http://www.dependencywalker.com/

有一个配置文件菜单,您可能希望确保选中跟随子进程选项。这将做两件事。首先,它可以让你看到所有被拉入的库版本。这对一些问题很有帮助。其次,运行时配置文件在运行子进程时使用调试内存管理器。因此,您将能够查看缓冲区是否溢出以及一些相关信息。

另一个有用的工具是 Mark Russinovich 的过程监视器:

http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx

该工具将报告所有文件、注册表和线程操作。这将帮助您确定是否遇到文件或注册表凭据问题。

Process explorer 为您提供了许多相同的信息:

http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx

这也是 Russinovich 的工具。我发现通过这个工具查看一些数据要容易一些。

最后,使用 windows 或 dev studio 的调试工具可以让您深入了解错误发生的位置。

于 2009-01-13T18:08:38.767 回答
1

访问冲突几乎总是一个内存错误——在这种情况下更有可能是因为它的随机崩溃(权限可能更明显可重现)。在 dll 的情况下,它可能是

  1. dll 本身的代码中存在错误 - 这可能类似于内存分配错误,甚至可能是简单的循环边界条件错误。

  2. 当 dll 尝试链接到系统上的另一个 dll 时出现错误。这通常是由于机器上的 dll 版本不匹配造成的。

您的第一步应该是尝试获得可重现的崩溃条件。如果您没有一系列会导致系统崩溃的情况,那么您将无法知道何时修复了它。

然后我会在干净的机器上安装系统并尝试在上面重现错误。运行监视器并准确检查程序崩溃时打开的其他文件(dll 等)。我见过在超线程 Pentium 上崩溃的代码,但在较早的 Pentium 上却没有——因此将旧机器恢复为测试平台可能是覆盖该机器的不错选择。改变机器中的 ram 数量也是值得的。

希望这些步骤可以为您提供线索。希望这将是一个环境问题,因此可以通过使用正确版本的 windows、dll 等来避免。但是,如果此时您仍然遇到崩溃而没有好的线索,那么您的选择是重写或尝试通过在汇编器杠杆处调试 dll 或将其反汇编来进一步查明问题。如果您不熟悉汇编代码,那么这两种方法都是遥不可及的,很难看出您将获得什么——而且任何一种选择都可能是一个巨大的时间槽。我自己过去遇到过这样的特别低级别的高强度问题,在“招聘编码器”网站之一上做广告,并寻找具有专业知识的人。同样,您将需要一个可重现的错误才能做到这一点。

从长远来看,必须更换没有源代码的 dll。聘请具有装配技能的专家来分析功能并为您提供流程图可能值得考虑。以受控的方式尽早执行此操作是一种良好的商业实践 - 例如在运行它的机器崩溃并且该版本的 windows 不再容易获得之后。

于 2009-01-13T17:19:16.027 回答
1

您可能想尝试使用Resource Hacker,您可能有幸反编译内部应用程序。它可能不会为您提供完整的源代码,但至少可能会提供有关该应用程序正在做什么的更多信息,这也可以帮助您确定罪魁祸首。

于 2009-01-14T17:21:13.540 回答
0

将最大可能的 RAM 添加到机器

这个简单而便宜的黑客过去对我有用。当然是 YMMV。

于 2009-01-13T16:52:07.313 回答
0

逆向工程是一种可能性,尽管很困难。
从理论上讲,您可以反编译甚至调试/跟踪已编译的 VB6 应用程序 - 这是容易的部分,在没有源代码的情况下修改它,除了最简单的情况外,这是困难的部分。

免费编译器/反编译器:

VB 反编译器

VB 调试器

在大多数情况下,重写将是解决问题的更成功和更快的方法。

于 2009-01-14T18:11:15.407 回答