我目前正在使用一个相当古老的Borland C ++应用程序,它使用ActiveX组件绘制一些图形。在应用程序中使用ActiveX comp的多个窗口。可以随时打开 - 这些可以显示相同的图形(不同的缩放系数等),也可以显示不同的图形。
应用程序用于定位,ActiveX正在绘制并显示不同单元的位置。
Borland应用程序每秒大约10次获得一个新职位,并找出哪些表单(及其ActiveX)需要知道更新的位置以便绘制它。这已经进行了很长时间,但我不得不在ActiveX中对新版本的产品进行一些更改。
大约一年前,我不得不对组件进行一些细微的更改,我发现应用程序可能以一种状态结束,导致组件中出现“索引越界”错误。结果不是显示错误或程序终止,而是应用程序开始使用大量内存 - 并且继续快速上升。在某些时候它停止了,有错误的组件只是停止显示任何东西(停止绘制自己)。
现在我已经做了最近的改变,我遇到同样的问题,其中一个组件似乎得到一个错误,没有显示,而是它没有重绘自己,并且内存使用正在天空 - 高。在某些PC上似乎会抛出访问冲突 - 这就是说错误发生在OCX中,但在我开发的PC上,我无法以任何方式获得此访问冲突。
此外,我无法准确追踪错误发生的时间 - 即导致错误的原因。我可以连续10次运行相同的设置15分钟,有时它会发生内存使用上升和组件错误,有时没有任何反应,它会在整个持续时间内运行。
由于它是OCX,因此使用regsvr32进行注册,因此代码不是主应用程序的一部分。因此我不能使用断点并以这种方式调试它。
我很确定组件内部发生了一些错误,但没有传递,所以我看不出它是什么。
所以有人知道如何调试这个吗?我可以以某种方式让OCX记录发生的任何错误,或者让它显示错误,或者我该怎么做?
任何帮助都将非常感激 - 一直试图追踪错误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 ++
C:\Program Files (x86)\Internet Explorer\iexplore.exe,Attach = Yes,Debugger Type=Native Only