【问题标题】:Delphi App has "No Debug Info" when DebuggingDelphi App 调试时出现“无调试信息”
【发布时间】:2012-01-09 19:01:13
【问题描述】:

我们已经构建了一个使用包和组件的应用程序。当我们调试应用程序时,IDE 中的“事件日志”通常会显示我们的 BPL 正在加载而没有调试信息(“无调试信息”)。这没有任何意义,因为我们所有的包和 EXE 都是用调试构建的。

_(each project) | Options | Compiling_
[ x ] Assertions
[ x ] Debug information
[ x ] Local symbols
Symbol reference info = "Reference info"
[   ] Use debug .dcus
[ x ] Use imported data references

_(each project) | Options | Linking_
[ x ] Debug information
Map file = Detailed

我们有 4 个项目,全部使用运行时包构建:

  1. Core.bpl
  2. Components.bpl
  3. Plugin.bpl(同时使用 #1 和 #2)
  4. MainApp.exe(使用 #1)

发现的问题

1) 很多时候,当我们调试时,Components.bpl 加载了调试信息,但是“局部变量”窗口中的所有值都是空白的。如果将鼠标悬停在代码中的变量上,则不会弹出窗口,并且 Evaluate 窗口也不会显示任何内容(“结果”窗格始终为空白)。

2) 有时事件日志显示各种 BPL 的“无调试信息”。例如,如果我们激活 Plugin.bpl 项目并将其设置为 Run |参数的 Host Application 为 MainApp.exe,然后按 F9,除了 Plugin.bpl 模块外,所有模块似乎都加载了“Has Debug Info”。加载时,事件日志显示“无调试信息”。但是,如果我们关闭应用程序并立即按 F9,它将再次运行它而不重新编译任何内容,这一次 Plugin.bpl 加载了调试(“有调试信息”)。

问题

1) 什么会导致“局部变量”窗口显示值?

2) 为什么当 BPL 符合 debug 并且所有调试文件(dcu、map 等)都可用时,有时会加载 BPL 而没有调试信息?

【问题讨论】:

    标签: delphi debugging delphi-xe2 packages bpl


    【解决方案1】:

    我会描述我的问题。

    我使用LoadPackage 函数动态加载包。

    我可以在SysInternals.com Process Monitor 中看到 packagename.DCP 在LoadPackage 处理后成功打开并读取 - 没有文件 I/O 失败,没有尝试在错误的位置找到它,没有任何可疑之处。 所以也许 DCP 中有一些结构让 IDE 调试器发疯。我渴望Turbo Debugger 可用于 Delphi 的时代

    顺便说一句,如果开发人员创建了 packagename.RSM,同样如此。

    然后(在断点或 Step Trace 处暂停时)我打开 View / Debug Windows / Modules 并看到最后一个模块是我的 - 它有空的“符号信息”单元格。我右键单击它,选择 “重新加载符号” 操作 - 就在这里,从现在开始我可以调试了。

    PS。不知道这是否可以帮助我调试初始化部分 - 希望“break on load”菜单项即使在动态 LoadPackage 调用中也能正常工作......

    PPS。它确实有效,即使在 IDE 重新启动时也是如此。所以现在我在 BPL 加载时收到 CPU View 的警报,我点击 CTRL+ALT+M,滚动到底部以找到我的 BPL,右击到 Reload Symbols,按 Enter,然后关闭 ModulesCPU 查看并点击F9 (Run)。在initialization 部分完成后,我再次收到CPU View 的提醒——在退出LoadPackage 之前只有几个JMPs——所以我关闭CPU View 并再次触发F9。相当乏味,但仍然比 IDE 重启好。

    【讨论】:

    • 不回答 为什么 缺少调试信息,但 +1 以获得有用的解决方法。这比重新启动 Delphi 并一次又一次地尝试直到它最终起作用要好得多。
    • 它没有丢失,它存在于 BPL 中 - CFF Explorer 显示了这一点。事实是 IDE 不使用它 - 它使用 DCP 文件代替。如果有多个 DCP 文件 - 那么它会失败。但是,为什么即使存在唯一的 DCP 并且它清楚地读取了该文件,它有时也会失败 - 这是个谜。在我的情况下,我发现同名单元 EXE:Path1\name 和 BPL1:Path2\name - 但是 BPL1 和 BPL2 加载正常,只有动态加载的 BPL3 受到影响。无论如何,SysInit 单元将被克隆到所有 EXE/DLL/BPL 文件中,因此不应混淆 IDE 调试器。神秘。 PS thx 2u 用于注意模块视图
    • 不客气——但我从未尝试右键单击告诉它“重新加载符号”。这是一个不错的新技巧。
    • 好久不见,詹姆斯。我刚刚发现,虽然我安装了 XE2 Upd4 HF1,但在 Windows\System32 中,我有 rtl160bpl 和 vcl160.bpl 一些以前的 2011 版本(update1?不知道)。所以 porgram 在c:\RAAD Studio\9.0\... 中针对 RTL/VCL 编译,并针对另一个 BPL 版本运行和调试。在 RTL 中进行调试、评估 variable.classname 等时也会遇到很多麻烦。我删除了那些遗留的全局 BPL,几个小时后这个问题没有重复。希望它不会再次发生或会更罕见
    • 这个答案在 2020 年被访问过,哇。前面提到的两个 BPL 是 XE2 Upd3 版本,由 (AFAIR) Raize CodeSite 远程日志插件安装。总体而言,第 4 次更新似乎质量不高,而且重要的部分被破坏了,例如 COM 与 Microsoft Office 的互操作
    【解决方案2】:

    我们在项目中遇到了类似的问题。不幸的是,我们有几十个 bpl,所以我们无法将它们合并为一个。 这个问题是在我们迁移到 XE2 并更改了编译目标的文件夹结构后出现的。 虽然很难说较新版本的 Delphi 是否引入了该问题,但我们可以通过在路径环境变量中添加编译 bpls 的文件夹来解决该问题。使用 IDE 的路径覆盖功能。 Delphi 2010 中不需要这种类型的配置...

    【讨论】:

      【解决方案3】:

      non-official tool 修复了 Delphi 的许多问题。它为我修复了没有调试信息的模块加载。全部归功于magicandre1981

      【讨论】:

      • 我在 Delphi XE6 中调试设计包时遇到问题,IDE 不想加载调试信息。这个工具有帮助,谢谢!
      • 每次遇到断点时,我也会登陆“CPU”选项卡 -> 我的 bpl 和应用程序在没有调试信息的情况下加载。我安装了这个工具,它只是工作。谢谢!
      • 这在 XE2 中并没有为我解决。疯狂的事情,据我所知,Andy 有 Delphi 源代码(不是 RTL/VCL。而是 IDE 本身),因此可以修复源代码级别的错误。为什么这些错误经常在 Delphi 版本中持续存在,这完全令人愤怒。
      【解决方案4】:

      您必须使用调试信息构建单独的包,并且您最终也希望在没有调试的情况下构建它们 - 因此您将在 2 个位置同时拥有它们。然后你想用调试信息构建你的应用程序项目。检查您的路径以确保您在调试项目构建中包含启用调试的包源。听起来您可能包含了在没有调试的情况下构建的包,因为您包含的源错误。您必须确保没有包含两个路径,让 Delphi 在两个地方找到相同的包时选择要包含的内容。

      【讨论】:

      • 我们所有的项目都是用调试构建的,并且 DEBUG 和 RELEASE 都使用相同的输出文件夹。因此,在没有 DEBUG 的情况下构建的包或调试器正在查找任何包的 RELEASE 版本都不是问题......我们将检查路径以确保正确找到调试 DCU。感谢您的建议。
      • +1 建议您检查路径。这使我打开了调试模块窗口,该窗口显示了调试符号的加载位置。这帮助我想到了解决问题的想法(见下面的答案)。
      【解决方案5】:

      对于我们的特殊情况,我们能够通过将 Core.pbl 和 Components.bpl 合并到一个 BPL 中来解决这个问题。现在所有模块都加载了调试信息,局部窗口不显示变量值的偶尔问题也得到了解决。

      【讨论】:

      • 结合 BPL 来解决问题并不是一个好的解决方案。想象一下,如果您有数百个动态包,则不可能组合成一个 BPL。
      • @ChauCheeYang - 我们确实有许多其他 BPL。只是这两者的分离导致了问题。在我们的例子中,将这两者结合起来是可以接受的——同时将其他几十个分开......它可能与 Components.bpl 有关,严重依赖于 Core.bpl。
      • 您是否对debugrelease 配置都使用了optset 参考?
      • 我发布了一个可能有助于解决问题的新答案。
      【解决方案6】:

      这个问题可能与QC#109291有关:

      当 Delphi IDE 开始引入 .dproj 文件并使用选项集构建配置时,它极大地改进了项目发布管理。

      但是,它也有一个难以重放和捕捉的副作用,我认为这是 IDE 中的错误。这个问题应该总是让一些项目无法在 IDE 调试器中调试的用户感到困惑。即使我们检查了项目中编译器和链接选项的所有相关设置,调试器也不会在项目上激活。有些项目有效,有些项目无效。我们甚至认为是内存问题还是cpu问题。

      我注意到问题是由于 .dproj 文件设置没有存储正确的信息。如果相关的 .dproj 文件有这样的内容:

      <PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
          <Cfg_1>true</Cfg_1>
          <CfgParent>Base</CfgParent>
          <Base>true</Base>
      </PropertyGroup>
      <PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
          <Cfg_2>true</Cfg_2>
          <CfgParent>Base</CfgParent>
          <Base>true</Base>
      </PropertyGroup>
      
      <Import Project="Release.optset" Condition="'$(Cfg_2)'!='' And Exists('Release.optset')"/>
      <PropertyGroup Condition="'$(Cfg_1)'!=''">
          <CfgDependentOn>Release.optset</CfgDependentOn>
      </PropertyGroup>
      <Import Project="Debug.optset" Condition="'$(Cfg_1)'!='' And Exists('Debug.optset')"/>
      <PropertyGroup Condition="'$(Cfg_2)'!=''">
          <CfgDependentOn>Debug.optset</CfgDependentOn>
      </PropertyGroup>
      

      Release.optset 绑定到Cfg_2Debug.optset 绑定到Cfg_1Release 配置使用Cfg_1Debug 配置使用Cfg_2

      在构建项目时,调试信息不​​会在调试配置中生成,而是在发布配置时生成。

      解决方法是使用任何文本编辑器打开 .dproj,但不使用 Delphi IDE,然后更新为:

      <Import Project="Release.optset" Condition="'$(Cfg_1)'!='' And Exists('Release.optset')"/>
      <PropertyGroup Condition="'$(Cfg_1)'!=''">
          <CfgDependentOn>Release.optset</CfgDependentOn>
      </PropertyGroup>
      <Import Project="Debug.optset" Condition="'$(Cfg_2)'!='' And Exists('Debug.optset')"/>
      <PropertyGroup Condition="'$(Cfg_2)'!=''">
          <CfgDependentOn>Debug.optset</CfgDependentOn>
      </PropertyGroup>
      

      【讨论】:

      • 这看起来很有希望,但我无法测试它,直到我再次遇到缺少调试信息的情况。感谢您分享您的经验。
      • 是的。我通过删除 dproj 文件并让 Delphi 重新生成它解决了许多问题。众多示例之一:stackoverflow.com/questions/21958575/…
      【解决方案7】:

      我在 .dprj 文件中发现 Cfg_2 详细信息中的一行,其值 Debugger_LoadAllSymbols 设置为 false。我确实将其设置为true。问题解决了。也许与您的情况不同,但可能会有所帮助。

      <PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
      ...
          <Debugger_LoadAllSymbols>true</Debugger_LoadAllSymbols>
      ...
      </PropertyGroup>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多