LLDB: 无法生成表达式的IR代码

56
当我运行单元测试并想要调试某些东西时,我会设置一个断点并输入例如“po myVariable”。我从LLDB获得的响应是:
错误:无法IRGen表达式,没有其他错误
示例:
我在这里定义了最小的单位测试:
class MyExampleTests: XCTestCase {
    func testLLDB() {
        let world = "World"
        print("Breakpoint goes here")
        print("Hello \(world)")
    }
}

我在“断点位置在这里”处设置了断点,当我运行时,我输入'po world':

(lldb) po world
错误: 无法 IRGen 表达式,没有其他错误

有任何建议可以让它评估我的表达式吗?

这不足以提供有用的答案。你能举个例子吗? - Jim Ingham
1
以上已编辑示例 - niklassaers
1
你找到这个问题的解决方案了吗?我也遇到了同样的问题。 - PinkiePie-Z
需要某些文件/文件夹的文件写入权限。我不知道哪个对象确切地需要这种权限,所以我已将其递归设置。例如,要为所有用户授予所有权限,请执行以下操作:sudo chmod -R 777 /base_path_to_swift/swift_folder - Antonio
请查看https://dev59.com/blQK5IYBdhLWcg3wHsZJ - MichaelV
8个回答

50

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

carthage update --platform iOS --no-use-binaries

2
清空Carthage/Build文件夹并重新构建依赖项也对我有所帮助。 - Bojan Dimovski
5
这是一个权宜之计,但如果你使用了许多依赖项,这可能需要很长时间。我仍在寻找更好的解决方案。 - Brian Kendig
谢谢,它刚刚起作用了。也许你可以解释一下 --no-use-binaries 选项背后的魔力是什么? - pjuzeliunas
4
默认情况下,Carthage会查找是否有可供下载的预构建框架(二进制文件),以便它不必在本地计算机上进行构建。问题是这些预构建框架不支持逐步调试,因此除非您在本地构建它们,否则调试将失败。 - Jonathan Cabrera

43

你可能会出现这个错误是因为你正在另一个项目/框架/模块中设置断点。

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

fr v world

1
不确定这是否是导致错误的原因,但解决方法有效,加一。 - XcodeNOOB
我不确定是否应该运行Jonathan Cabrera发布的命令,但我尝试了fr v world而不是po world,它起作用了! - Samuel Folledo
“po”,“vo”和“fr v”有什么区别?你会在什么情况下使用它们中的一个? - Reimond Hill
@ReimondHill 很好的问题!我的最佳建议是阅读有关每个选项的信息。查看此WWDC视频,这是一个很好的开始:https://developer.apple.com/videos/play/wwdc2019/429/ -- 另外,在调试器中,如果po不能用,请尝试使用p,然后最后尝试fr v - nodebase

10

编辑:

鉴于这个答案受到了一些关注,请注意,这只是一个快速解决方法。
如果你经常遇到这个问题,请查看其他答案以获取更持久的解决方案。
对我来说,清除构建文件夹就解决了。
编辑2:在某些情况下,清理不起作用,carthage update --platform iOS --no-use-binaries 对我总是有效的。

原始答案:

我有一个快速而简单的解决方案可以使它正常工作。

  • 在调试导航器中选择第一个可访问的框架,通常是 mainenter image description here

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

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

我不知道为什么它能工作,但对我来说确实有效。我只是偶然发现了它。
我很想听听更有见解的人的解释(我的项目中使用了Carthage)。


这太疯狂了。感谢您的帖子。这对我有用,Xcode版本为11.5。 - Christopher
在Xcode 14.3中工作。 - Juraj Antas

4

在我的情况下,我只是重新启动了Xcode,现在一切正常 :)


这是最被低估的答案,有一点……+1(而且SO AI过滤掉了赞誉,想象一下我的震惊) - Alex
并不是这样。我从13.5升级到13.6的Xcode,但错误仍然存在。我认为仅仅重新启动Xcode并没有太大的关联。 - Wingzero

3

如果你正在使用CocoaPods,这可能适用于你。有两件事情需要确保。

注意事项1:请确保您没有在Podfile中将pod依赖项添加到测试目标:

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

在我的情况下,我使用了不少框架,其中至少一个使用了二进制文件,如果将其添加到我的测试目标中会导致LLDB异常。

作为一个小提示,如果需要在应用程序中使用任何依赖项,您需要通过启动参数更改主应用程序的运行时行为,而不是在测试代码中执行操作。(这就是我偏离正道并导致问题的原因。)您可以通过将以下内容添加到测试文件来实现:

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

接着在您的主应用程序代码中(例如在AppDelegateSceneDelegate中):

#if DEBUG
if CommandLine.arguments.contains("testing-enabled") {
    configureAppForTesting()
}
#endif

#if DEBUG并不是必需的,但最好不要发布不会被执行的代码。

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

例如,如果我们创建了一个名为App Store的构建配置,基于Release,以及一个基于Debug的测试配置,则我们需要在Podfile中执行以下操作:

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

  # ... pod dependencies, etc.
end

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

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

Xcode scheme config screen


为了记录,我正在使用的CocoaPods版本是1.9.1和Xcode 11.4。语法和功能可能会在未来发生变化... - istvanp

2

你可以尝试使用netx命令:

根据你安装swift的位置而定,以我个人为例,是在/opt/swift/

sudo chmod 644 /opt/swift-3.1.1/usr/lib/swift/CoreFoundation/*

1
这应该被接受。很遗憾这个有价值的答案没有得到它应有的尊重! - progyammer
2
似乎Swift不再安装在/opt/目录下。 - Jonathan Cabrera
2
有人找到了新的Swift位置吗? - tzuer
2
@tzuer 在 Xcode 10 上的 Swift 位于 /usr/bin/swift 中。您可以在终端中键入 which swift 以查找其位置。 - kakubei
4
现在应该使用哪个命令?sudo chmod 644 /usr/bin/swift/? 答案会将 chmod 644 应用于当前 Swift 版本的 CoreFoundation 内的所有文件。有人知道 CoreFoundation 在哪里吗? - regina_fallangi
10
什么是“netx命令”?为什么更改整个CoreFoundation目录的模式可以修复“Couldn't IRGen expression”错误? - Brian Kendig

1

0

我曾经也因为Instabug框架遇到了完全相同的问题。

如果您找不到解决方案,那么您应该通过在调试器中运行log enable lldb expr -f /some/path/to/save/logs命令来导出LLDB日志,并检查该文件中的故障,因为这是帮助我的方法。

此外,您应该在http://bugs.swift.org/上提交错误报告,并将LLDB日志附加到其中。


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