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

时间:2012-09-06 10:03:09

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

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

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

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

大约一年前,我不得不对组件进行一些细微的更改,我发现应用程序可能以一种状态结束,导致组件中出现“索引越界”错误。结果不是显示错误或程序终止,而是应用程序开始使用大量内存 - 并且继续快速上升。在某些时候它停止了,有错误的组件只是停止显示任何东西(停止绘制自己)。

现在我已经做了最近的改变,我遇到同样的问题,其中一个组件似乎得到一个错误,没有显示,而是它没有重绘自己,并且内存使用正在天空 - 高。在某些PC上似乎会抛出访问冲突 - 这就是说错误发生在OCX中,但在我开发的PC上,我无法以任何方式获得此访问冲突。

此外,我无法准确追踪错误发生的时间 - 即导致错误的原因。我可以连续10次运行相同的设置15分钟,有时它会发生内存使用上升和组件错误,有时没有任何反应,它会在整个持续时间内运行。

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

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

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

任何帮助都将非常感激 - 一直试图追踪错误3天,没有任何结果。

3 个答案:

答案 0 :(得分:10)

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

让您走向正确方向的小例子:

假设您写了一个名为myctl.ocx的OCX,它会在添加到Wordpad文档时崩溃。调试方法是将调试器附加到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中的任何内容。当Wordpad在myctl.ocx内崩溃时,它应该显示源代码和所有内容,再次假设它位于可访问的位置。

答案 1 :(得分:1)

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

至少我会接近它。

答案 2 :(得分:1)

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

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