jjzjj

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

coder 2024-02-08 原文

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

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

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

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

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

此外,我无法准确追踪错误发生的时间 - 即导致错误的原因。我可以在 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 文件实现了在调试器中单步执行源代码、查看局部变量、在监 window 口中正确查看数据类型的所有魔力。

当 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 Symbol Servers 自动获取丢失的符号文件。

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

假设您编写了一个名为 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 中崩溃时,它应该会向您显示源代码和所有内容,再次假设它位于可访问的位置。

关于c++ - 如何调试 ActiveX 控件 (OCX) 或使其记录错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12297579/

有关c++ - 如何调试 ActiveX 控件 (OCX) 或使其记录错误?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  7. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  8. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  9. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  10. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

随机推荐