Exc_Breakpoint (Sigtrap) on Production Version Only

Why does force Unwrapping give me an EXC_BREAKPOINT (SIGTRAP) Error?

Turns out this was not about force unwrapping but was due to the EKParticipant.url property returning nil when it contained a String contained a " character.

let attendee = Attendee(name: participantName, email: participant.URL.resourceSpecifier!.lowercaseString, required: isRequiredParticipant, hasAccepted: hasAccepted)

We used this to access the participants email but any read or write operation to the url caused a crash so we took the EKParticipant.description property and parsed the email using a regular expression.

let participantEmail = participant.description.parse(pattern: emailRegex).first ?? ""

What could be the cause of an occasional failure to create an encrypted Realm object?

The init method

I'm going to get this out of the way first: It's unlikely that this has anything to do with your crash in this instance, but when you override any init method, you should always call super's version of that init method unless there is no super class or no available superclass implementation to call. In Objective-C you assign the results of [super init] to self, however, this pattern was not adopted by swift and it is unclear, from Apple's documentation, what happens when you call super.init() from a direct NSObject subclass in Swift. I'm running out of steam at this hour, thought I did spend some time looking at the apple/swift GitHub repository Apple/Swift Github among other place and was unable to find any really satisfying information about calling NSObject init from a Swift subclass. I would definitely encourage you to continue the search if you really want to know more and not just take my word for it. Until then, it is highly unlikely that it will cause issues if you call NSObject's init() from a Swift subclass and it just might save your butt at some point too! ;)

The crash

If the reason for the Realm crash is because getKey() fails, then why would that be failing?

I'm not sure why getKey() might be failing, but it's unlikely this is the cause of your crash. I believe default values for properties are available by the time code inside init() is called in which case your app would crash before it reached that call inside init(). I will do a little more research on this tomorrow.

If thats not the cause, that what are other reasons for the failure?

I've looked at the Realm API you are using there and it's unclear why the call to Realm(configuration:) is failing although clearly that's expected to be possible since the call can throw. However, the documentation doesn't state the conditions under which it will throw.

And is there anything the code can do (such as retry to create the Realm object) if there is a failure?

Yes! Fortunately, the "try" mechanism has other variation than just "try!". Actually, in this case, the reason the app appears to be crashing is that you are using try! which in production code should only be used in situations where you know the call is extremely unlikely to ever fail such as retrieving a resource your app ships with from inside it's app package. Per Apple's documentation:

Sometimes you know a throwing function or method won’t, in fact, throw an error at runtime. On those occasions, you can write try! before the expression to disable error propagation and wrap the call in a runtime assertion that no error will be thrown. If an error actually is thrown, you’ll get a runtime error. Swift Error Handling Documentation

When it comes to impacting the user experience, I always like to err on the side of caution so I would be highly surprised to find even one occurrence of try! in any of my code (even Swift playground toys and experiments).

In order to fail gracefully and retry or take another course of action your code either needs to use try? which will convert the thrown error to an optional as in:

if let realm = try? Realm(configuration: configuration) {
// Do something with realm and ignore the error
}

Or you can use a full try-catch mechanism like so:

let realm: Realm? = nil
do {
realm = try Realm(configuration: configuration)
// do something with realm
} catch let e {
realm = nil
// do something with the error
Swift.print(e)
}

Or alternatively:

do {
let realm = try Realm(configuration: configuration)
// do something with realm
} catch let e {
// do something with the error
Swift.print(e)
}



So this may not be your golden ticket to never having this Realm call fail, but I hope it provides some help towards making your code a little more robust. I apologize for any errors, it's getting late for me here. Good luck and cheers! :)

iOS app crashes with EXC_BREAKPOINT (SIGTRAP) in AppDelegate.applicationWillResignActive

I contacted Apple TSI and they told me to check that the object inside the applicationWillResignActive and applicationWillTerminate method is nil. And to my surprise at the moment of calling applicationWillTerminate the object is really nil.

But can anyone explain how this is possible? This object is initialised in didFinishLaunchingWithOptions and I never make it equal to nil during the app life cycle. Is it possible that iOS is trying to terminate the application for some reason (not enough memory, for example) and tries to remove all objects from memory one by one, and when applicationWillTerminate is called, object is already removed from memory and therefore it is nil? But at which point it's allowed to nil out a variable of a running class?

UPDATE:

I got a response from the Apple team and I think it's very interesting. They said that didFinishLaunchingWithOptions will ALWAYS be called before other lifecycle delegates for
the "standard" lifecycle like applicationWillResignActive and
applicationDidEnterBackground. However, that's NOT the case with applicationWillTerminate. The
termination process can occur outside the normal lifecycle flow and, at
least in theory, there's not reason it couldn't occur before
didFinishLaunchingWithOptions is actually called.

So if I have an optional variable in AppDelegate that is initialized inside didFinishLaunchingWithOptions, it can still be nil in applicationWillTerminate. This is what causes some users to crash.



Related Topics



Leave a reply



Submit