9

是否可以远程调试在 VB6 之外启动的进程?

该应用程序是一个 VB6 应用程序,具有相当多的 dll/ocx 资源。我正在尝试使用无注册 COM 设置 VB6 应用程序的 ClickOnce 部署,但在执行时出现错误。

我对 VB6 重定向 COM 注册方式的理解可能意味着这是不可能的,但我认为有人可能有更好的主意。

4

3 回答 3

9

为了支持 Darryl 建议Windbg的回答- 这是 Microsoft 人员2006 年关于将 Windbg 与 VB6 结合使用的博客文章,以及另一位 Microsoft 人员 2004 年关于 Windbg的简要介绍的博客文章。

编辑:只是为了让它完全清楚。Windbg 是来自 Microsoft 的免费独立调试器。将您的 VB6 EXE、DLL 和 OCX 编译为带有符号的本机代码(创建 PDB 文件),您将能够调试 ClickOnce 应用程序。

博客的关键摘录:

如果您对服务器计算机的访问权限有限,则可以使用 WinDbg 的远程调试工具。以通常的方式将 WinDbg 的副本附加到进程,然后将其转入调试服务器(查看 WinDbg 帮助中的 .server)。然后,您可以从 WinDbg 的“文件”菜单远程连接到它。除了服务器机房风扇没有噪音之外,它就像在那里一样。调试远程时,您的 WinDbg 副本只是一个非常智能的终端,因此所有扩展、符号等都必须在远程服务器上。您为任何 DLL、VB6 或 .NET 设置完全相同的方式。

在您的组件加载之前,您的组件的符号不会加载,因此您必须让服务器运行至少那么长时间。如果你想在那个时候停止调试器,你可以在你的 VB 代码中提前中断,但是如果你这样做了,请记住它会在每次通过代码时停止。假设您让它运行然后闯入。如果您使用“x MyModule!*”列出模块的加载符号,那么您将看到您的所有函数以及捆绑在那里的许多符号。VB 毫不掩饰地添加了接口和符号,但您通常不需要担心这些。可能看起来很奇怪的一件事是所有类/方法语法都使用 C++ 双冒号约定而不是友好的小点。

从这里,您可以以通常的方式(bp 等)设置断点并逐步执行代码。您也可以使用 F9 打开 VB 源代码模块并在其中设置断点,尽管 VB 文件扩展名不在源文件类型下拉列表中。单步执行代码是有启发性的,但如果您以前没有看过 VB 为您生成的代码,可能会有点令人担忧。您将逐步浏览汇编程序,其中有很多 COM goo。Hresults 得到了很多检查。您可能需要经常参考源代码来确定您的位置,因为需要一些练习才能知道源代码的样子。变体尤其具有挑战性,因为 VB 在那里为您做了很多工作,看起来像一个简单的等式可能会导致大量代码。

通过这种方式获取数据并不容易。当您查看局部变量(dv 是命令)时,您可能会看到变量被简单地列为 eclipsed,这意味着内存在函数生命周期内也被用于其他用途,或者名称在此上下文中不是唯一的. 枚举仅显示为整数或长整数,对象显示为指针。事实上,它们总是如此,但 VB IDE 对您隐藏了这一点。VB 字符串实际上是 COM BSTR(以及相应的 Unicode),而字节数组实际上是 char 数组。您可能会惊讶地发现 VB 字符串是 Unicode,因为 VB 似乎只支持 ANSI。那是因为 Ruby 表单引擎只是 ANSI。

您将无法获取 Err、App 或 Printer 对象,因为您需要通过许多内部且完全未记录的结构来获取它们。即使您可以到达那里,它们也只是没有您在 VB 中使用的访问器函数的原始数据。如果您需要查看这些字段中的任何一个,最好的办法是在源代码中嵌入调试代码,以将它们的值复制到您可以获得的位置。

如果需要,您可以进入 VB 运行时,但如果您尝试调试应用程序,它可能不会很有启发性。如果这样做,您会注意到 VB 的内部结构受 COM 的影响很大。影响实际上是两个方面的,因为一些 COM 想法最初来自 VB。

运行代码时您可能会看到异常。空引用异常(即取消引用空指针)并不少见或任何需要担心的事情。它们将显示为地址为 0 或几乎为 0 的第一次机会 C000005 异常。如果有对象设置为空,运行时有时会这样做,但这是安全的,因为唯一可能的值是 null 或有效值。如果您的代码在集合中进行查找并且值不存在,您也会看到异常。因为异常现在非常昂贵,所以如果可以的话,您可能希望避免这样做。您通常会看到的另一个例外是 c000008f。如果您查看该数字,您会发现它是一个浮点不精确结果异常。

调试 VB 组件中的挂起和崩溃的方式与任何其他非托管组件的调试方式非常相似,但由于上述编译,它会稍微困难一些。如果您必须尝试以这种方式调试 VB 代码,我强烈建议您从“Hello world”应用程序开始,然后逐步进行。VB 可能是一种易于编码的语言,但所有的东西使它成为一种糟糕的调试语言。

于 2009-02-05T23:01:34.220 回答
3

我相信在 VB6 中调试时,它不会附加到正在运行的二进制文件,而是在它自己的进程中解释代码。这就是为什么任务管理器和 Win32 API 在调试时将 VB6.exe 显示为正在运行的应用程序的原因。

正如您所说,VB6 有时会短路对 COM 库的调用,因此并非总是可以拦截这些调用。

您可能不得不求助于智能日志记录(即记录您遇到错误的点周围的变量值,以期找到它发生的代码行和/或相关变量的状态.)

祝你好运

于 2009-02-05T22:13:53.253 回答
3

你试过windbg吗?只要确保你有项目的 pdb 文件。

于 2009-02-05T22:20:45.907 回答