如何调试ActiveX控件(OCX)或使其记录错误

How can I debug an ActiveX control (OCX), or make it log errors?

本文关键字:记录 错误 OCX ActiveX 何调试 调试 控件      更新时间:2023-10-16

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

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

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

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

现在,随着我最近所做的更改,我遇到了同样的问题,其中一个组件似乎出现了错误,没有显示出来,而是没有重新绘制自己,内存使用率极高。在一些电脑上,似乎抛出了访问违规-也就是说错误发生在OCX中,但在我开发的电脑上,我无论如何都无法获得此访问违规。

此外,我也无法准确地追踪错误发生的时间(造成错误的原因)。我可以在15分钟内连续运行相同的设置10次,有时内存使用量会增加,出现组件错误,有时什么都不发生,并且在整个过程中正常运行。

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

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

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

如果有任何帮助,我们将不胜感激——我们已经尝试追踪错误3天了,但没有任何结果。

本质上是在询问如何调试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:somethingmyctl.ocx,它将查找C:somethingmyctl.pdb。如果它能找到它,它就会使用它,并且您可以使用丰富的调试器支持来调试DLL。如果它找不到它,你将处于现在的位置——DLL调用是一个你看不到的黑匣子。

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

让你走上正确方向的小例子:

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

'wordpad.exe': Loaded 'C:Program FilesWindows NTAccessorieswordpad.exe', Symbols loaded (source information stripped).
'wordpad.exe': Loaded 'C:WindowsSystem32ntdll.dll', Symbols loaded (source information stripped).
'wordpad.exe': Loaded 'C:WindowsSystem32kernel32.dll', Symbols loaded (source information stripped).
'wordpad.exe': Loaded 'C:WindowsSystem32KernelBase.dll', Symbols loaded (source information stripped).
...

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

'wordpad.exe': Loaded 'C:somethingmyctl.ocx', Symbols loaded.

有了这一点,您可以使用源代码和所有内容调试myctl.ocx中的任何内容。当写字板在myctl.ocx内部崩溃时,它应该向您显示源代码和所有内容,同样假设它位于可访问的位置。

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

至少我会这么做。

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

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