LLDB:无法表达IRGen

nik*_*ers 32 xcode ios lldb

当我运行单元测试并想要调试某些东西时,我设置了一个断点并输入例如"po myVariable".我从LLDB得到的答复是:

error: Couldn't IRGen expression, no additional error
Run Code Online (Sandbox Code Playgroud)

例:

我有这里定义的最小的小单元测试:

class MyExampleTests: XCTestCase {
    func testLLDB() {
        let world = "World"
        print("Breakpoint goes here")
        print("Hello \(world)")
    }
}
Run Code Online (Sandbox Code Playgroud)

我在"Breakpoint goes here"中设置断点,当我跑步时,我做'po world':

(lldb) po world
error: Couldn't IRGen expression, no additional error
Run Code Online (Sandbox Code Playgroud)

有关如何使其评估我的表达的任何建议吗?

Jon*_*era 24

我使用Carthage框架遇到了同样的问题,并通过删除项目根目录中的Carthage文件夹并强制Carthage从源代码重建框架,让LLDB调试器再次工作:

carthage update --platform iOS --no-use-binaries
Run Code Online (Sandbox Code Playgroud)

  • @pjuzeliunas Carthage 默认情况下会查找是否有可供下载的预构建框架(二进制文件),这样就不必在您的计算机上本地构建它们。问题是这些预构建的框架不支持逐步调试,因此除非您在本地构建它们,否则调试会失败。 (4认同)
  • 这是一种解决方法,但是如果您使用大量依赖项,则可能会花费很多时间。我仍在寻找更好的解决方案。 (3认同)
  • 清除“Carthage/Build”文件夹并重建依赖项也对我有帮助。 (2认同)

nod*_*ase 24

您可能会收到此错误,因为您正在另一个项目/框架/模块中设置断点。

而不是po world,最快的解决方案是使用以下命令:

fr v world
Run Code Online (Sandbox Code Playgroud)


de.*_*de. 8

编辑:

由于这个答案引起了一些关注,请注意它只是描述了一个快速修复。
如果您经常遇到该问题,请查看其他答案以获得更持久的解决方案。
对我来说,清理构建文件夹就成功了。
编辑 2:清洁在某些情况下没有帮助,carthage update --platform iOS --no-use-binaries总是对我有用。

原答案:

我有一个快速而肮脏的解决方案,使这项工作。

  • 在调试导航器中选择第一个可访问的帧,通常 main在此处输入图片说明

  • 例如,在调试器中键入一些内容 po self

  • 在调试导航器中选择原始帧并执行您的命令,它现在应该可以工作了

我不知道为什么它有效,但它对我有用。我只是偶然发现的。
我很想听听有更多见解的人的解释(我在我的项目中使用 Carthage)。


ist*_*anp 3

如果您使用CocoaPods,这可能适用于您。有两件事需要确定。

陷阱 1:确保您没有pod在以下位置添加对测试目标的依赖项Podfile

target 'MyApp' do
  project 'MyApp'

  pod 'Alamofire'
  # ... other pods ...

end

target 'MyAppTests' do
  project 'MyApp'
  inherit! :search_paths
  # Do not add your main app pods here
  # You can use pods for writing your test cases though (e.g. mocks)
end
Run Code Online (Sandbox Code Playgroud)

就我而言,我有相当多的框架,其中至少有一个使用二进制文件,如果我将其添加到我的测试目标中,就会导致 LLDB 崩溃。

作为旁注/提示,如果您需要在应用程序中使用任何依赖项,则需要通过启动参数更改主应用程序的运行时行为,而不是在测试代码中执行操作。(这是我偏离路径的地方,它给我带来了问题。)您可以通过将其添加到测试文件中来做到这一点:

# When you launch your app (e.g. in `setUpWithError()`)
let app = XCUIApplication()
app.launchArguments = ["testing-enabled"]
app.launch()
Run Code Online (Sandbox Code Playgroud)

然后在您的主应用程序代码中(例如在AppDelegate或中SceneDelegate):

#if DEBUG
if CommandLine.arguments.contains("testing-enabled") {
    configureAppForTesting()
}
#endif
Run Code Online (Sandbox Code Playgroud)

#if DEBUG不是必需的,但最好不要发布不会在已发布的应用程序中执行的代码。

陷阱 2:如果您有自定义构建配置,请确保您的测试在Debug模式下运行。

例如,如果我们创建了一个名为App Storebased on的构建配置Release和一个基于 的测试配置Debug,那么我们需要在我们的 中执行以下操作Podfile

target 'MyApp' do # do it for MyAppTests also!
  project 'MyApp', 'App Store' => :release, 'Test' => :debug

  # ... pod dependencies, etc.
end
Run Code Online (Sandbox Code Playgroud)

如果没有此设置,您的依赖项将使用默认的 iOS 配置来构建,这是一种Release配置(针对调试器不喜欢的SwiftGCC进行了编译器优化)。

最后,确保您的方案的测试模式设置为使用正确的构建配置(在本例中Test),如下面的屏幕截图所示。

Xcode 方案配置屏幕