代码之家  ›  专栏  ›  技术社区  ›  benPearce

VB6中的远程调试

  •  9
  • benPearce  · 技术社区  · 16 年前

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

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

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

    3 回复  |  直到 16 年前
        1
  •  9
  •   StayOnTarget Charlie Flowers    6 年前

    支持Darryl的回答 Windbg -这是一个 2006 blog post 一位微软员工介绍了如何将Windbg与VB6结合使用,以及 2004 blog post 另一位微软员工简要介绍了Windbg。

    编者:我只是想说清楚。Windbg是微软提供的免费独立调试器。将VB6 EXE、DLL和OCX编译成带有符号的本机代码(创建PDB文件),您就可以调试ClickOnce应用程序了。

    博客的关键摘录:

    如果您对服务器计算机的访问权限有限,则可以使用 Winchester的远程调试工具。将Winchester副本附加到 以通常的方式处理,然后将其提交给调试服务器 (请查看Winchester帮助中的.server)。然后,您可以连接到它 远程从Winchester的“文件”菜单。这就像 除了服务器机房风扇没有噪音。什么时候 调试一个远程设备,你的Winchester副本只是一个非常智能的终端 因此,所有扩展名、符号等都必须位于远程服务器上。 对于任何DLL、VB6或。网。

    在您的组件加载之前,您的组件的符号不会加载 所以你必须让服务器至少运行那么长时间。你可以把 如果你想在VB代码的早期中断调试器 那一点,但如果你做到了,记住每次都会到此为止 通过代码。让我们假设你让它跑,然后闯入。 如果您使用“x MyModule!*”列出模块的加载符号 然后,您将看到所有函数以及许多符号 为你裹在里面。VB添加了相当多的接口和符号 不知羞耻,但你通常不需要担心这些。一个人 可能看起来很奇怪的是,所有的类/方法语法 使用C++双冒号约定,而不是友好的小冒号 点。Winkey不明白VB是不同的,它被对待了 就像任何带有符号的DLL一样。

    从这里开始,您可以按照通常的方式(bp等)和步骤设置断点 通过代码。您还可以打开VB源代码模块并设置 虽然VB文件扩展名不在F9中,但它们中有断点 源文件类型下拉列表。一步一步地浏览代码就会发现 但如果你没有看到VB的代码,可能会有点令人担忧 之前为您生成。您将逐步完成组装程序 里面有很多COM goo。结果经常被检查。 您可能需要经常参考来源,以确定在哪里 你是因为需要一点练习才能知道 源代码看起来像。变体尤其具有挑战性,因为 VB在那里为你做了很多工作,看起来很简单 这个方程可能会产生大量的代码。优化后的代码是均匀的 更难,因为执行顺序通常与 这可能是你所期望的,而且比平时更难看到数据。

    通过这种方式获取数据并不容易。当你观察局部变量时 (dv是命令)那么你可能会看到变量只是简单地列出了 被遮蔽,这意味着记忆正被用于某事 否则也在函数生命周期内,或者名称不是 在这种情况下是独一无二的。枚举只显示为整数或长整型 对象显示为指针。事实上,他们一直都是这样,但是 VB IDE对您隐藏了这一点。VB字符串是COM BSTR(和 因此,Unicode)的封面和字节数组实际上是char 阵列。你可能会惊讶地发现VB字符串是Unicode 因为VB似乎只支持ANSI。即 因为Ruby表单引擎只支持ANSI。运行时转换 Ruby和API调用的ANSI的Unicode字符串,尽管有一些方法 如果你愿意,可以通过Unicode。

    您将无法访问Err、App或Printer对象 因为你需要经历很多内部和完全 没有文件记录的结构来对付他们。即使你能到达那里, 它们只是原始数据,没有您所使用的访问器函数 在VB中使用。如果你需要查看这些字段中的任何一个,最好的选择是 是在源代码中嵌入调试代码,以将其值复制到 你可以到达的地方。

    如果你愿意,你可以进入VB运行时,但可能不会 如果你想调试你的应用程序,这很有启发性。如果你这样做, 您会注意到VB内部非常受COM的影响。这个 由于一些COM思想来自VB,因此实际上是双向的 原来。

    运行代码时可能会看到异常。空引用 异常(即取消引用空指针)并不罕见,或者 有什么好担心的。他们将以C000005的第一次机会出现 地址为0或几乎为0的情况除外。运行时有时会这样做 如果有对象设置为空,但这是安全的,因为 只有可能的值是null或有效值。你也会看到 如果您的代码在集合中进行查找,并且值为 不在那里。因为现在例外非常昂贵,你可能想要 如果可以的话,尽量避免这样做。另一个例外,你会 常见的是c000008f。如果你查一下这个号码,你会发现 这是一个浮点不精确结果异常。它用于 这里的意思不同,因为我们没有生成真正的浮点 不精确的结果异常,可以安全地抛出它们来指示VB 正常可捕获类型的错误。

    VB组件中的挂起和崩溃调试在很大程度上是在 与任何其他非托管组件的方式相同,但它只是一点点 由于上述汇编,难度更大。如果你一定要试试 以这种方式调试VB代码,我强烈建议您开始 在“Hello world”应用程序上向上学习。所有的东西 VB作为一种易于编写代码的语言,可能会使其成为一种糟糕的语言 调试。

        2
  •  3
  •   Kribensa    16 年前

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

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

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

    祝你好运

        3
  •  3
  •   Darryl Braaten    16 年前

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