【问题标题】:How can I debug an ActiveX control (OCX), or make it log errors?如何调试 ActiveX 控件 (OCX),或使其记录错误?
【发布时间】:2012-08-31 03:01:01
【问题描述】:

我目前正在使用一个相当老的 Borland C++ 应用程序,它使用 ActiveX 组件来绘制一些图形。在应用程序中使用 ActiveX 组合的多个窗口。可以随时打开 - 这些可以显示相同的图形(不同的缩放系数等),也可以显示不同的图形。

应用程序是定位的,ActiveX是绘制和显示不同单元的位置。

Borland 应用程序大约每秒 10 次获得一个新位置,并找出哪些表单(及其 ActiveX)需要知道更新后的位置才能绘制它。这已经进行了很长时间,但我不得不在 ActiveX 中为新版本的产品做一些更改。

大约一年前,我还不得不对组件进行一些小改动,我发现应用程序可能会以某种状态结束,从而导致组件中出现“索引越界”错误。这样做的结果不是显示错误或程序终止,而是应用程序开始使用大量内存 - 并且一直在快速增长。在某些时候它停止了,出现错误的组件只是停止显示任何东西(停止绘制本身)。

现在,随着我最近所做的更改,我遇到了同样的问题,其中一个组件似乎出现错误,没有显示出来,而是它没有重新绘制本身,并且内存使用量越来越大-高的。在某些 PC 上,似乎引发了访问冲突 - 这表示错误发生在 OCX 中,但在我开发的 PC 上,我无法以任何方式获得此访问冲突。

我也无法准确追踪错误发生的时间 - 即导致错误的原因。我可以在 15 分钟内连续运行 10 次相同的设置,有时会发生内存使用增加和组件错误,其他时候什么也没有发生,并且在整个持续时间内运行正常。

由于它是一个 OCX,它是使用 regsvr32 注册的,因此在代码方面不是主应用程序的一部分。因此我不能使用断点并以这种方式调试它。

我很确定组件内部发生了一些错误,没有传递,所以我看不到它是什么。

那么有人知道我该如何调试吗?我能否以某种方式让 OCX 记录发生的任何错误,或者让它显示错误,或者我能做什么?

任何帮助将不胜感激 - 3 天以来一直在尝试追踪错误,但没有任何结果。

【问题讨论】:

  • 你能修改或构建ocx吗?如果您有 ocx 的 PDB 文件,则可以对其进行调试 - 只需将调试器附加到正在运行的进程即可。
  • 我确实可以修改和构建ocx。我完全不熟悉 MFC 和 OCX,所以我不太清楚如何使用 PDB 文件并将调试器附加到正在运行的进程?

标签: c++ debugging mfc error-handling activex


【解决方案1】:

本质上,您是在问如何调试 DLL。 OCX 只是一个加载到进程中的 DLL 文件。这是一个有点宽泛的话题,但我会尝试做一个简短的开始:

DLL / EXE / OCX 文件在 Windows 编程环境中通常被称为“模块”。它们基本上都是一样的。为了清楚起见,我将在这里称它们为 DLL。

调试器(Visual Studio 和 Borland 既是调试器也是 IDE)像寄生虫一样“附加”到进程,允许您执行设置断点、读取进程内存、查看堆栈跟踪等操作。它们可以查看/操作该进程的所有内存和资源,包括所有 DLL。

DLL 不包含太多帮助调试器的信息,即使在调试版本中也是如此。它们基本上只包含二进制机器代码,如果您使用调试器进入 DLL 调用,您将只能看到汇编代码——而不是原始源代码。函数只是内存中的地址,局部变量甚至是不可见的;你只会得到一些指向堆栈内存的指针。

PDB 文件(“程序数据库”)包含所有附加信息和元数据,供调试器执行操作,例如将内存中的地址映射到源代码行、局部变量、数据类型、函数签名等。这些信息称为“调试符号”或只是“符号”。当 Visual Studio 构建一个 DLL 时,它会输出一个相应的 PDB 文件。正是这个 PDB 文件实现了在调试器中单步调试源代码、查看局部变量、在监视窗口中正确查看数据类型的所有魔力。

当 Visual Studio 的调试器附加到进程并看到正在加载的 DLL 时,它会搜索其对应的 PDB 文件。它在许多地方寻找这个 - 其中最简单的是在与 DLL 相同的文件夹中。所以如果你加载了C:\something\myctl.ocx,它会寻找C:\something\myctl.pdb。如果它可以找到它,它将使用它,您可以使用丰富的调试器支持来调试 DLL。如果它找不到它,您将回到现在的位置 - DLL 调用是一个您无法看到的黑盒子。

Microsoft 甚至为 Windows DLL 提供 PDB 文件,例如 ntdll.dll。必须根据需要下载它们。 Visual Studio 可以通过转到Tools -> Options -> Debugging -> Symbols 自动执行此操作,并且应该有一个选项可以使用 Microsoft 符号服务器自动获取丢失的符号文件。

小例子让你朝着正确的方向前进:

假设您编写了一个名为myctl.ocx 的OCX,它在添加到写字板文档时会崩溃。调试的方法是将调试器附加到wordpad.exe。我相信在 Visual Studio 中是 Debug -> Attach to Process。附加后,您甚至可以在输出窗口中看到:

'wordpad.exe': Loaded 'C:\Program Files\Windows NT\Accessories\wordpad.exe', Symbols loaded (source information stripped).
'wordpad.exe': Loaded 'C:\Windows\System32\ntdll.dll', Symbols loaded (source information stripped).
'wordpad.exe': Loaded 'C:\Windows\System32\kernel32.dll', Symbols loaded (source information stripped).
'wordpad.exe': Loaded 'C:\Windows\System32\KernelBase.dll', Symbols loaded (source information stripped).
...

您可以看到 Visual Studio 如何加载为这些文件提供一些额外信息的 PDB 文件(符号文件)。当您加载myctl.ocx 时,您也会看到该行。如果myctl.pdb 可以访问,它也会加载它。

'wordpad.exe': Loaded 'C:\something\myctl.ocx', Symbols loaded.

有了这个,你可以用源代码和一切调试myctl.ocx中的任何东西。当写字板在myctl.ocx 内崩溃时,它应该会显示源代码和所有内容,再次假设它位于可访问的位置。

【讨论】:

  • 感谢您提供的重要信息。我听说 VS 可以附加到进程以调试 dll 等,但不知道它是如何工作的。在您的帮助下让它工作并发现了错误。再次感谢:)
【解决方案2】:

向 OCX 添加代码,该代码会打开一个文件并打印正在发生的事情,可能带有时间戳。日志内容可能包括执行流程、输入值、关键变量值、重要的内部状态。

至少我会这样处理它。

【讨论】:

  • 也是我最初的想法,但我确信通过记录来追踪问题需要太多的时间和精力,并希望有另一种更好的方法。
【解决方案3】:

如何在IE.10 + WIN8 64bit + VS2008中调试OCX/C++

  • 在vs2008中构建你的ocx,在你的html中添加ocx CSID标签。
  • 将 TabProcGrowth 保持为中等(不会更改!!)
  • 使用命令C:\Program Files (x86)\Internet Explorer\iexplore.exe,Attach = Yes,Debugger Type=Native Only设置VS2008 OCX项目调试
  • 打开 Internet Explorer 10 窗体 WIN8 任务栏。
  • 在 Internet Explorer 10 的 url 中键入目标 ocx htm 文件路径。然后按 enter 键加载 htm。
  • ocx 已加载,您需要启用 IE.10 ActiveX 模式。
  • 当 IE10 准备好 ActiveX 模式时,运行 VS2008 OCX 项目,该项目会将 IE10 附加到断点。
  • 再次刷新 IE.10 html 以重新加载 ocx 并开始调试您的 ocx 源代码。

【讨论】:

  • 我修正了你的格式……如果可能的话,尽量让内容更具可读性。谢谢!
  • 我得到“无法启动程序 [以上命令]” 系统找不到指定的文件。如果我删除你的参数,它会启动 IE。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-05
  • 2012-02-16
  • 2011-12-23
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 2014-10-23
相关资源
最近更新 更多