55

When I'm running a unit test and want to debug something, I set a breakpoint and type for instance "po myVariable". The response I get from LLDB is:

error: Couldn't IRGen expression, no additional error

Example:

I have the smallest little unit test defined here:

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

I set my breakpoint in "Breakpoint goes here", and when I run, I do 'po world':

(lldb) po world
error: Couldn't IRGen expression, no additional error

Any suggestions to how I can make it evaluate my expression instead?

shim
  • 9,289
  • 12
  • 69
  • 108
niklassaers
  • 8,480
  • 20
  • 99
  • 146
  • That's not enough information to give a useful answer. Can you give an example of this failing? – Jim Ingham May 16 '17 at 01:37
  • 1
    Edited with example above – niklassaers May 16 '17 at 18:11
  • 1
    Have you found a solution to this question? I'm facing the very same problem. – PinkiePie-Z Jul 25 '17 at 07:53
  • File write privilege is required for some files/folder. I do not know which object exactly requires the privilege, so I have set it recursively. On instance, to give all privileges for all users, do the following: `sudo chmod -R 777 /base_path_to_swift/swift_folder`. – Antonio Jul 29 '17 at 03:36
  • take a look at https://stackoverflow.com/questions/52420272/error-couldnt-irgen-expression-no-additional-error – MichaelV Oct 07 '18 at 12:46

8 Answers8

50

I was having the same issue using Carthage frameworks, and got the LLDB debugger working again by deleting the Carthage folder in the project root and forcing Carthage to rebuild the frameworks from source:

carthage update --platform iOS --no-use-binaries
Jonathan Cabrera
  • 1,656
  • 1
  • 19
  • 20
  • 2
    Clearing out the `Carthage/Build` folder and rebuilding the dependencies helped me as well. – Bojan Dimovski Nov 29 '18 at 14:02
  • 5
    That's a workaround, but if you use a lot of dependencies, this can take a lot of time. I'm still searching for a better solution. – Brian Kendig Feb 12 '19 at 21:50
  • Thank you, it just worked. Maybe you can explain what is the magic behind `--no-use-binaries` option? – pjuzeliunas Dec 20 '19 at 07:09
  • 4
    @pjuzeliunas Carthage by default looks up to see if there are prebuilt frameworks (binaries) available to download, so that it doesn't have to build them locally on your machine. The problem is that those prebuilt frameworks don’t support step-by-step debugging, so the debugging fails unless you build them locally. – Jonathan Cabrera Dec 24 '19 at 18:58
40

You are likely getting this error because you are setting a breakpoint in another project/framework/module.

Instead of po world, the quickest solution is to use the following command:

fr v world
nodebase
  • 2,510
  • 6
  • 31
  • 46
  • 1
    Not sure that this is the reason we get this error. but the workaround is working, +1. – XcodeNOOB Jun 18 '20 at 15:13
  • Not sure if I should run the command posted by Jonathan Cabrera, but I tried `fr v world` instead of `po world` and it worked!! – Samuel Folledo Aug 16 '20 at 08:02
  • What's the difference between "po", "vo" and "fr v"? When will you use one or the other? – Reimond Hill Feb 18 '21 at 15:31
  • @ReimondHill Good question! My best advice is to read about each one. Checkout this WWDC video for a good place to start: https://developer.apple.com/videos/play/wwdc2019/429/ -- also, when you're in the debugger, try using `po` if that doesn't work try `p`, then finally try `fr v`. – nodebase Feb 19 '21 at 16:13
10

edit:

Since this answer gets some attention, please note that it describes just a quick fix.
If you encounter the problem frequently, check the other answers for a more permanent solution.
For me, cleaning the build folder did the trick.
Edit 2: Cleaning doesn't help in some cases, carthage update --platform iOS --no-use-binaries always does for me.

original answer:

I have a quick and dirty solution that makes this work.

  • select the first accessible frame in your debug navigator, usually mainenter image description here

  • type something in the debugger, for example po self

  • select the original frame in the debug navigator and execute your command, it should work now

I don't know why it works, but it does for me. I just found out by chance.
I'd be interested to hear an explanation from somebody with more insights (I am using Carthage in my project).

de.
  • 7,068
  • 3
  • 40
  • 69
4

In my case, I just restarted Xcode, and it's good :)

Anton Malmygin
  • 3,406
  • 2
  • 25
  • 31
  • This is the most underrated answer, have a point... +1 (and SO AI filters out kudos, imagine my shock) – Alex Dec 06 '19 at 09:50
  • not really. I upgrade from 13.5 to 13.6 Xcode, still the error. I think just restarting Xcode is less relevant. – Wingzero Aug 06 '20 at 07:10
3

If you are using CocoaPods, this may apply to you. There are two things to make sure of.

Gotcha 1: Make sure you have not added pod dependencies to your Test target(s) in your 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

In my case I had quite a few frameworks and at least one of them was using binaries and caused LLDB to freak out if I added it to my test target.

As a side note/tip, if you need to use any dependencies from within your app, you need to change the runtime behavior of your main app via launch arguments instead of doing things in your testing code. (This is where I strayed from the path and it caused me problems.) You can do this by adding this to your test file:

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

and then in your main app code (e.g. in AppDelegate or SceneDelegate):

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

The #if DEBUG is not necessary but it's good practice to not ship code that will not be executed in the published app.

Gotcha 2: If you have custom build configurations, make sure your tests run in Debug mode.

For example, if we have created a build config called App Store based on Release and a test config based on Debug, then we need to do the following in our Podfile:

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

  # ... pod dependencies, etc.
end

Without this setting, your dependencies will be built using the default iOS config which is a Release type of configuration (with compiler optimizations for both Swift and GCC that the debugger won't like).

Finally, make sure that your scheme's Test mode is set to use the proper build configuration (in this case Test) as in the screenshot below.

Xcode scheme config screen

istvanp
  • 4,423
  • 3
  • 24
  • 26
  • For posterity, the version of CocoaPods I am using is 1.9.1 and Xcode 11.4. Syntax and features might change in the future... – istvanp Apr 14 '20 at 03:16
2

you can try with netx command: Depend where you have install swift, in my case is in /opt/swift/

sudo chmod 644 /opt/swift-3.1.1/usr/lib/swift/CoreFoundation/*
jherran
  • 3,337
  • 8
  • 37
  • 54
Jorge Omar MH
  • 491
  • 5
  • 7
1

CocoaPods Binary (https://github.com/leavez/cocoapods-binary) was causing this problem for me. Ended up removing it to fix the problem.

Fogh
  • 1,275
  • 1
  • 21
  • 29
0

I had the exact same problem because of the Instabug framework.

If you can't find a solution then you should export the LLDB logs by running the log enable lldb expr -f /some/path/to/save/logs command in the debugger and check for failures in that file because that's what helped me.

Also, you should file a bug report on http://bugs.swift.org/ with the LLDB logs attached to it.

arturgrigor
  • 9,361
  • 4
  • 31
  • 31