Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Instantiated optional variable shows as nil in Xcode debugger

Since I upgraded to Xcode 11 and Swift 5.1 I've encountered a strange issue -- after an optional variable is instantiated, it can still show as up nil in the Xcode debugger!

I have an optional class variable called booking:

var booking: Booking?

It's of type Booking:

public struct Booking: Codable {
    var id: Int?
    var start_time: Date?
    var payment_currency: String = "USD"
    var payment_amount: Int?
}

When I'm stepping through the code, I can see booking before it's allocated... It's nil, great:

enter image description here

Then after it's allocated... What, still nil??:

enter image description here

I wondered if it was being treated like a lazy variable somehow. But it's not really nil, because it can be accessed:

enter image description here

After searching for a while, I wondered if my build schema in Xcode didn't have its "Debug executable" flag set. But it does. I even cleaned and rebuilt the project with the flag off and on to be sure.

enter image description here

Whether I view booking in the Variables View or enter p booking in the Console View, it shows up as nil.

What's going on here? I need the predictability of debugging I had before this upgrade.

UPDATE

I distilled a simple way to reproduce the issue. First, create an empty single-view project and add this to the top of AppDelegate.swift:

public struct Booking: Codable {
    var start_time: Date?
    var payment_currency: String = "USD"
}

Then add these lines to the application(_:didFinishLaunchingWithOptions:) func:

booking = Booking()
print("booking.payment_currency = \(booking?.payment_currency ?? "NULL")")

Set a breakpoint as before and when running, notice that the debugger shows booking as nil even after being assigned, as in my original case.

Then comment out the start_time variable, re-run, and notice that now the debugger shows booking having a value after being assigned, as one would expect.

So it seems that Date variables, optional or not, in a struct like this make debugging confusing. Specifically Date variables -- change the variable to other types like Int, Int?, String, String?... and there's no issue.

Unless I'm missing something very basic, this seems like a bug in the Xcode debugger to me. If so, would the best way to report it be at https://developer.apple.com/bug-reporting/?

like image 534
Dylan Avatar asked Sep 26 '19 02:09

Dylan


People also ask

How do I debug a variable in Xcode?

When you run an application in Xcode, the debugger is automatically started and attached to the process of the application. Click the Run button in the top left or press Command + R. From the moment the application is up and running, we can start inspecting the process and, if necessary, debug it.

What is debug in Swift?

Swift is tightly coupled to the version of the Swift compiler embedded in the debugger. Tight integration of compiler and debugger enables accurate inspection of Swift types as well as full-featured expression evaluation in the context of a rapidly evolving language.


2 Answers

It appears I've found a bug in Xcode 11. It's easily reproducible as outlined in the UPDATE above. I've filed the bug with Apple.

I'm still looking for a workaround now, since I use quite a few structs containing Date variables. If anybody can find one, please comment below.

like image 161
Dylan Avatar answered Oct 20 '22 20:10

Dylan


The cause of the bug is not that var start_time: Date? is present or absent, but that Date is a Swift Foundation overlay. If you remove the Codable conformance and make start_time an NSDate?, everything is fine. So clearly LLDB gets confused by Swift overlay types like Date?.

In this linked question, we see the same issue with URL?. If we change it to NSURL? everything is fine.

I'm not saying that that's a viable workaround! You want and need to use Swift types. I'm just saying that this is what is messing up LLDB. You can include that info when you report the bug.

This bug is slated to be fixed in Xcode 12.5.

like image 14
matt Avatar answered Oct 20 '22 20:10

matt