Dissecting Swift Crashlogs

Crashlogs for Swift apps have a bunch of problems and terminology that's not defined anywhere public that I can find.


Why do stack frames that show the filename often show a line number of zero? Like (Filename.swift:0) instead of the real line number.


What do these things mean:


protocol witness


merged


function signature specialization <Arg[0] = Owned To Guaranteed, Arg[1] = Owned To Guaranteed>


partial apply forwarder for closure #1


merged closure #1


reabstraction thunk helper from @callee_owned () -> () to @callee_unowned @convention(block) () -> () (NetworkReachabilityManager.swift:0)


?

Replies

Most of these are just implementation details, so they don't necessarily "mean" anything in a larger sense. If you want to ask people who know the details, ask your question over on forums.swift.org.


Here's what I know about a couple of them:


A protocol witness table is a descriptor of where to find the implementation details of a type's conformance to a protocol. (The position within the table is specific to the protocol, the information at that position is specific to the type.)


A function signature specialization is a version of a generic function signature that as a specific type, as opposed to the generic type.


"Owned to guaranteed" sounds like ARC ownership information, perhaps allowing some unnecessary retains and releases to be eliminated.


Partial application is a way of applying some parameters to a function (or closure), but not all of them, producing a slightly different closure with fewer parameters.


Reabstraction is probably a technique for modifying a calling convention from one "abstraction" (calling convention, data representation, etc) to another, for example when calling C or Objc-C functions, or passing native Swift data structures. A thunk is, of course, a tiny piece of code that allows one kind of code to transfer to a different kind of code.

Thanks.


The reason I ask what they mean is I'm trying to decipher crashlogs that have those terms strewn all over the place.


So it looks like the stack frames that have a zero line number may be methods or closures that are not directly in my code but which were generated by the compiler. This seems to include protocol witnesses. Callback methods for notifications seem to have an extra method generated by the compiler that has a matching prototype but zero line number. Similar for IBActions. Maybe being declared @objc causes this.

So the compiler can modify a closure if it's receiving an optional parameter and the optional isn't being sent?

Anyway, this makes a few things clearer.

>>Maybe being declared @objc causes this.


Being declared @objc (in a native Swift class, I would assume) causes the Swift compiler to create two methods. One is the pure Swift method using Swift calling conventions and a mangled name, used when the compiler can see or infer a "final" attribute at a call site (so dynamic dispatch can be bypassed for efficiency). The other method uses Obj-C calling conventions and the Obj-C name, and is dynamically dispatched. Internally, that method just calls the pure Swift method. (So an explict "dynamic" attribute forces the compiler to always dispatch dynamically through the Obj-C method, which is necessary for KVO, for example.)


>>So the compiler can modify a closure if it's receiving an optional parameter and the optional isn't being sent?


Optional parameters aren't optional in the compiled code. The default value is inserted at the call site.


I don't know details of partial application offhand, but I think one idea is that you can take an instance method (which basically has an invisible first parameter 'self'), inject a value of self, yielding what is effectively a static method with the rest of the parameters. Or, you can inject all the other parameters, yielding a method that just takes a 'self' parameter, which may be easier for the compiler to pass around since it now has a fixed structure, and just needs an actual instance to supply the 'self' value.


Anyway, forums.swift.org is where you'll find the people who know this stuff.

I understand, and share, your frustration here. The Swift runtime is complex and it’s going to take a while for the Apple community in general to come up to speed on all the complexities. However, there is a bunch of info out there that you might find useful:

I haven’t yet got around to watching the last one, but it looks super interesting.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"