如何调试ActiveX控件(OCX)或使其记录错误
How can I debug an ActiveX control (OCX), or make it log errors?
我目前正在使用一个相当旧的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源代码
- Qt 错误:QSqlQuery::value:尝试从表中检索统计信息时未定位在有效记录上 (QComboBox)
- 记录重新引发错误的函数
- 分段错误:从文件中访问csv记录时转储了核心
- 正在将DJI错误代码记录到流中
- 我的游戏引擎的 spdlog 日志记录出现奇怪的"unresolved external symbol"错误
- 使用 Nvidia NPP 调整图像大小时未记录的大小调整错误
- 从接收中获取未记录的错误代码
- 我必须将记录结构转换为一类,并且不断遇到多个错误
- 尝试将数据从记录读取到程序(C++)时难以捉摸的错误
- 记录使用 createprocess 函数调用的 exe 的错误
- CDao记录集::查找错误
- 在记录错误时取消引用 ptr 的设计是错误的
- 激活记录是否用于查找错误行
- OpenGL 上下文创建期间未记录的错误
- 如何调试ActiveX控件(OCX)或使其记录错误
- 如何将从Google AddressSanitizer抛出的错误记录到日志文件中
- 在 C++11 应用程序中进行错误日志记录的优雅方法
- 在C++中记录 SEH 错误
- Boost.记录GNU/Linux下的链接错误
- 在 C 中执行期间记录错误