如何调试Delphi IDE?

13
如何调试Delphi IDE的详细步骤是什么?
我了解到,需要创建一个项目,并在该项目的调试器设置中将项目的“宿主应用程序”设置为Delphi(C:\ Program Files \ Borland \ BDS \ 3.0 \ Bin \ bds.exe)。然后,在调试器中运行项目(通过按F9键),第二个Delphi IDE实例应该出现。
我已经完成了上述步骤。但是,在以调试模式运行项目时,我没有看到第二个Delphi IDE实例打开。
动机
有一个VCL组件,我有源代码,可以正常构建,编译和安装。但是,当它放置在项目的表单中时,当您关闭表单时,Delphi会挂起。因此,我想找出为什么Delphi在带有此组件的窗体上退出时会冻结。(在设计时挂起,关闭项目时)。

6
您所说的"debug"是指查看另一个进程(第二个IDE)在调试器(第一个IDE)下运行,还是实际上想要找到并消除某个bug?我问这个问题是因为问题和标题让人觉得您想要对IDE本身进行调试!您肯定可以在调试器下看到它运行,但查找和消除错误是另一回事:您需要源代码才能做到这一点,而您没有IDE的源代码! - Cosmin Prund
1
抱歉没有表达清楚。有一个VCL组件,我已经拥有源代码,可以成功构建、编译和安装。但是,当它被放置在项目中的一个窗体上时,当你关闭该窗体时Delphi会卡住。因此,我想找出为什么Delphi在窗体上使用这个组件时退出会冻结。 - user1202134
1
我已将您的澄清作为编辑添加到问题本身中,因为那是每个人寻找澄清的地方。请问您是否意思是说您只有一个DPK作为活动项目,您将其主机应用程序设置为Delphi IDE,然后点击运行,但它没有启动IDE?它还会做其他事情吗?例如:它会给您显示错误消息吗? - Cosmin Prund
看看 Raize 的 CodeSite。为组件操作的所有参数和输入输出添加 Codesite.Send 行。有一个 IDE 实用程序可帮助完成所有函数的此操作。这将帮助您了解正在发生什么以及原因。而且它不会像弹出消息框等那样干扰操作。 - mj2008
https://www.idefixpack.de/blog/2018/12/debugging-the-rad-studio-ide/ - Gabriel
4个回答

10

你的项目很可能是EXE类型。 EXE类型的项目不需要宿主应用程序,因此该设置被忽略,没有其他IDE被启动。至少,你应该将你的项目设置为DLL类型:这将启动第二个IDE,但不会很有帮助。

你提到的技术通常用于调试你的设计时包项目。创建一个设计时包项目,将其安装到IDE中,将项目的宿主应用程序设置为IDE,设置一些断点,按下F9,第二个Delphi副本将启动。

你也可以通过手动启动第二个复制品,然后使用“运行”菜单中的“附加到进程”命令来“调试”Delphi IDE,但这不会很有用,因为你不能轻易地找到你的代码以设置断点。


1
抱歉没有表达清楚。有一个VCL组件,我已经拥有了源代码,可以成功构建、编译和安装。但是,当它被放置在项目中的一个窗体上时,当你关闭该窗体时,Delphi会卡住。因此,我想找出为什么Delphi在窗体上使用这个组件时退出会冻结。 - user1202134
谢谢Cosmin Prund。您的回答有效地解决了获取第二份IDE运行的问题。现在我可以开始调试组件了。 - user1202134

3

首先,我会检查挂起是否在运行时和设计时都发生。 在您的运行时代码中动态实例化组件。 如果挂起仍然发生,则可以使用单个调试器实例正常地逐步执行组件的源代码。 除非行为仅在IDE进程内发生,否则无需调试到正在运行的IDE实例中。


挂起只发生在设计时而不是运行时。如果我创建一个简单的项目,带有一个窗体,在其中放置问题组件并运行该项目,则它可以正常运行,甚至可以正常终止。但是,当我尝试在IDE中关闭该项目或退出打开该项目的Delphi时,Delphi就会挂起。因此,我想找出是什么原因导致IDE挂起。 - user1202134

1

首先找到并打开组件包,将运行时和设计时包的构建选项从“发布”更改为“调试”,如果它们还没有被更改,则重新构建。

然后保存一个包含两个项目(一个是设计时,一个是运行时,在某些特殊情况下,人们只有一个包,即设计时+运行时在一个包中)的项目组。

然后按照步骤将BDS.exe设置为主机应用程序。

我会尝试向你知道出现问题的组件添加一些OutputDebugString消息:

构造函数:

constructor TMyComponent.Create(AOwner:TComponent);
begin
    inherited;
    // other stuff.
    OutputDebugString('Created TMyComponent');
end;

析构函数:

destructor TMyComponent.Destroy(AOwner:TComponent);
begin
    OutputDebugString('Destructor TMyComponent starts');
    inherited;
    // other stuff.
    OutputDebugString('Destructor TMyComponent finish');
end;

TMyComponent所在单元的Finalization部分:

 finalization
      OutputDebugString('Finalization section for Unit MyComponentUnit');
 end.

通过 Delphi 调试器中的输出事件页面,您可以了解代码执行到哪个步骤,即使您没有异常断点可用于相对准确地定位缺陷,您也可以使用像上面那样的 OutputDebugString 消息,或者您甚至可以在 Delphi 中设置 非断点断点,并关闭断点属性“断开异常”,而是设置“日志消息”。这些消息(断点消息)的好处是不需要对组件造成任何损害,以便将一些简单的“打印语句调试”功能添加到您的调试工具包中。


原帖中提到:“...这是关于一个VCL组件的问题,我有源代码”。除非你知道一些没有在这里发布的信息,否则似乎与缺少源代码的DPK无关。 - Cosmin Prund
好的观点。我的答案基本上是相反的布尔运算,与所需的不符。已修复。 - Warren P

1
如果第二个 Delphi 实例没有启动,则您的 bds.exe 路径不正确。

路径是正确的,因为我通过右键单击 Delphi 2005(bds.exe)快捷图标并复制其目标位置来获取位置。如果我将整个路径粘贴到资源管理器窗口中,Delphi 2005也会启动。因此路径是正确的。 - user1202134

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接