【问题标题】:What's the solution for "error: Couldn't IRGen expression, no additional error" on Xcode 10.1?Xcode 10.1 上的“错误:不能 IRGen 表达式,没有其他错误”的解决方案是什么?
【发布时间】:2019-07-13 13:25:49
【问题描述】:

我们有一个大型项目,其中有很多通过 Carthage 引入的依赖项。每当我们尝试在 lldb 调试器 (p variablename) 中查看变量时,它都会给我们一个错误:error: Couldn't IRGen expression, no additional error

没有一种解决方法非常好。我们可以使用--no-use-binaries 运行 carthage 来绕过它,但它会使构建花费非常长的时间。我们可以在一些变量上使用fr v,但不是全部。人们已经在以前版本的 Xcode 中通过更改某些 Swift 目录的权限来解决此问题,但我在 Xcode 10.1 中找不到相应的目录。我看到有人说来回更改构建系统对他有帮助,但这对我们没有用。

因此,我开始专门针对 Xcode 10.1 寻找解决方案。有没有其他人发现是什么导致了这个错误,和/或一个好的解决方案?

【问题讨论】:

  • 我们似乎最终找到了问题的根本原因:我们的依赖项之一缺少头文件。当我们在依赖项中包含头文件时,主项目就可以在 lldb 中显示变量信息,而不会遇到任何麻烦。我们不明白为什么这个简单的修复解决了神秘的错误,但我们可以接受。

标签: swift xcode lldb carthage


【解决方案1】:

我团队中的某个人分享了一个实际可行的解决方案(我不知道他是发现它还是在其他地方找到它):

在 AppDelegate didFinishLaunchingWithOptions 方法的第一行设置断点。将此断点的操作设置为:po application

现在,当您运行应用程序时,调试器将在该断点处暂停,并将在 lldb 调试器窗格中显示此文本(使用您的应用程序名称而不是 Foo):

note: Swift compiler options for Foo conflict with options found in other modules; Switching to a new expression evaluator for Foo, old $R variables are lost.

然后lldb调试器将正常工作,能够p和po变量和expr表达式。

我不知道它为什么有效,但它有效,而且可靠!

【讨论】:

  • 谢谢,我工作了。在我尝试删除 carthage 缓存和派生数据之前,删除 carthage 文件夹,杀死 Xcode 并重建所有内容,但它不起作用。我已经在本地安装了两个 Xcode 版本,但是我使用运行应用程序的同一个构建了 carthage 依赖项,所以再次感谢,这让我发疯了。
  • 不幸的是不适合我。有一些来自 firebase 和其他地方的二进制文件。希望我知道是哪个模块导致了这个问题。
【解决方案2】:

我和一位同事找到了解决方案:

在您的 Swift 项目中创建一个 Objective-C 文件。当它要求桥接头时点击是。

Test.h

#import <Foundation/Foundation.h>

@interface Test : NSObject

- (id)init;

@end

Test.m

#include "Test.h"

@implementation Test

- (id)init
{
    return self;
}

@end

MyProject-Bridging-Header.h

#include "Test.h"

现在:? 不再有 error: Couldn't IRGen expression, no additional error,您可以再次调试。

所以我认为只是添加一个桥接头作为一种解决方法......

但如果这不起作用:

像这样在application: UIApplication, didFinishLaunching 中的AppDelegate.swift 中添加断点,希望对您有所帮助:

【讨论】:

    【解决方案3】:

    目前有一个硬性要求,即您用于构建源代码的 swift 编译器版本和用于调试它的 lldb 版本必须来自同一个工具链。目前,类型的 swift 调试信息只是内部 swift 编译器数据结构的序列化。它还依赖于本地路径信息,因此很难移动。

    更改该设计需要长期努力,但目前您必须在每次更新工具时重新构建所有二进制文件,并且不能使用预构建的二进制文件。

    但是,我有点惊讶这会导致日常问题。仅当您从 Carthage 提取新资源或更新工具时才需要进行这种完全重建,这不应该那么频繁。如果您比这更频繁地触发重建,则可能是依赖项没有得到正确跟踪,因此重建的文件比需要的多?

    【讨论】:

    • “相同的工具链”到底是什么意思?我们所有的依赖项都是用 Xcode 10.1 构建的,除了我们拥有的一些第三方依赖项,但我们通常不会调试那些。如果我正在使用使用旧 Xcode 构建的某个依赖项的版本进行构建,为什么这会阻止我在我的一个未使用该依赖项的类中的方法中查看局部变量?
    • 如果没有成功导入完整的模块依赖树,lldb 无法为表达式评估(或变量检查)构建快速上下文。 lldb 尝试创建一个通用上下文,其中包括加载到正在运行的应用程序中的所有模块,因此您可以使用任何东西。在你的情况下这将失败。
    • 从 Xcode 10 开始,如果失败,我们会构建一个新的上下文,它只会看到由包含您当前在调试器中停止的代码的模块导入的模块。如果该模块在其导入的关闭中不包含第三方模块,那么您应该没问题。当然,除了您将无法访问此模块不可见的类型/变量/等。但如果当前模块确实导入了您的第三方依赖项,我们又会遇到同样的问题。
    • 对于“相同的工具链”:lldb 包括 swift 编译器源代码的副本作为其构建的一部分。 swift 编译器源的副本,以及用于构建您构建代码的 swiftc 的副本,必须是相同的源。
    • 我们正在解决这个问题,但我们正在使用 Rome (github.com/blender/Rome) 来缓存我们的框架,因为每次构建它们都会浪费大量的开发人员时间。有没有我们可以用来进行调试的解决方法?
    猜你喜欢
    • 2019-02-24
    • 2019-03-13
    • 1970-01-01
    • 2016-06-21
    • 2022-06-27
    • 1970-01-01
    • 1970-01-01
    • 2023-02-20
    相关资源
    最近更新 更多