Xcode 8.1 & Swift SegFaults

Just updated to Xcode 8.1 and a large project I've been working on all year is now having terrible compile errors that I don't have any idea what to do with. Please note that under Xcode 8.0 this project was compiling just fine.


When I compile now, I get:

Command failed due to signal: Segmentation fault: 11


This pops up for 8 different source files, and when I get into the logs, I see:

1. While resolving type Region at [/Users/knassar/dev/oarc/OArcDOM/OArcDOM/Region.swift:107:11 - line:107:11] RangeText="R"
2. While resolving type Parametric at [/Users/knassar/dev/oarc/OArcDOM/OArcDOM/Region.swift:12:22 - line:12:22] RangeText="P"
3. While type-checking 'init' at /Users/knassar/dev/oarc/OArcDOM/OArcDOM/Element.swift:56:12
4. While type-checking 'init' at /Users/knassar/dev/oarc/OArcDOM/OArcDOM/Element.swift:103:12
5. While type-checking 'init' at /Users/knassar/dev/oarc/OArcDOM/OArcDOM/Element.swift:106:21
6. While resolving type Parent at [/Users/knassar/dev/oarc/OArcDOM/OArcDOM/Element.swift:106:46 - line:106:46] RangeText="P"
7. While type-checking 'init' at /Users/knassar/dev/oarc/OArcDOM/OArcDOM/Parametric.swift:68:12
8. While type-checking 'init' at /Users/knassar/dev/oarc/OArcDOM/OArcDOM/Parametric.swift:77:21


It's worth noting that of the 8 source files which generate this error, most are unrelated to the class graph described in that trace.


However, I've found that if I go to the init method at Parametric:77:

    public required init(json: JSON, parent: Parent) {
        super.init(json: json, parent: parent)
    }


And comment this function out, the segmentation faults go away. Yay!


However, of course I then get the following error:

/Users/knassar/dev/oarc/OArcDOM/OArcDOM/Parametric.swift:76:1: 'required' initializer 'init(json:parent:)' 
must be provided by subclass of 'Element'


How can I win here? And what has changed between Swift 3.0 (Xcode 8.0) and Swift 3.0.1 (Xcode 8.1) ??


Please help!!!

Accepted Reply

A segfault during compilation is a compiler bug, and there's nothing you can do about it, unless you are lucky enough to find a slightly different way of writing the same source code that doesn't crash. The segfault doesn't necessarily indicate anything wrong with your code.


All you can do is submit a bug report ASAP, and use whatever ugly workaround you can come up with, until a new version of the compiler is released.


I suggest you give Xcode 8.2 beta 2 a try. You won't be able to release the app until 8.2 is officially released, but it shouldn't be very long until it is.


Note that, in theory, you can download a newer Swift toolchain from swift.org and use it in Xcode 8.1, but I don't know how well this works in practice. Alternatively, you can try going back to an older Xcode and/or toolchain to avoid the problem.


If none of that is useful, then you should perhaps go to the discussion groups on swift.org and ask about the problem there. You might get a suggestion for cleaner workaround, or help using a newer Swift in 8.1.

Replies

For the time, I just have questions for you.


Is Parametric an external library ?


Was it updated with 8.1 ?


Did you check that the initializer must not be failable ?

No, all relevant classes are types declared in my code. This project is a framework within a larger application codebase. And the entire codebase compiled just fine under Xcode 8.0 just yesterday, I've been going through the app and upgrading each piece to Swift 3.0.1. This is the first of the frameworks in the workspace that has caused any problems.


The types are related in a class graph within the framework like so:

Parent
  |
  +---> Parametric
         |
         +---> Element


I'm suspecting that the Swift compiler is having trouble resolving this graph because the the required initializer init(json:parent:) declared in Element contains a parameter of type Parent... But this is necessary to my data modeling... it's not something I can refactor out, and this is the foundational data model to my entire app, and nothing works without it...


and again, this was working fine yesterday!


Any and All help would be much appreciated, as I'm essentially sunk without a solution here.

More Info:


I've confirmed that there's something going on with the class-graph resolution by collapsing the Parent type down into the Parametric type... The seg-fault goes away and the framework compiles fine.


While diagnosticly helpful, this isn't an acceptable solution, because it contradicts the actual data-modeling, and increases overall confusion and reduces the type-safety of the relevant types, requiring many new optional parameters on Parametric (ie: Not all Parametric Elements are Parents)


So my question goes back to, how can I actually solve this problem?

May be this will help you to solve the init call problem.

Coming from NatashaTheRobot May 30, 2016:


basememara.com/common-initializer-patterns-swift/



Common Initializer Patterns in Swift

Interesting solution for when you need to initialize a variable with another variable that needs to be initialized first - a super frustrating problem in Swift. Not sure how comfortable I feel about this solution, but it seems better than other things I've done (including making something a var instead of a let just for this reason).

Thanks, but that isn't actually relevant, as the issue isn't an initialization order issue, but rather a Type compilation order issue. IE: It's not a problem with instance variables, rather the problem seems to be the compiler is unable to compile the initializer


init(json: JSON, parent: Parent)


on Element or Parametric because it hasn't compiled the type Parent yet... and it cannot compile Parent because it is a sub-class of Parametric.


This is clearly a new bug, as this code has been compiling fine up until Xcode 8.1

I have a functional work-around, but I'm not at all satisfied with it.


The work-around:

I created a protocol called Parentable and changed the required initializer on Element to:

public required init(json: JSON, parent: Parentable)


Then made the Parent type conform to Parentable:

public class Parent: Parametric, Parentable {


And poof all the problems disappear.


This is not a good solution, though, because it creates a new irrelevant protocol which polutes the namespace and adds code-complexity only to satisfy a bug in the compiler. What's even worse is that because this is a required initializer and the class is public, even though the initializer is only ever used within this framework (ie: it's effectively internal) it must be declared public because it's a required initializer in a public class, and therefore the protocol Parentable must be public too! Which means this effectively pollutes the down-stream namespaces throughout the app with a completely useless protocol that should never even exist.

😠 ➖ 😟

Cannot you create a header file, so that comiler will be warned of coming definition ?


As described here :

http : / / stackoverflow.com/questions/24098408/how-can-i-add-forward-class-references-used-in-the-swift-h-header

It's a pure-swift framework...


But thanks! 🙂

A segfault during compilation is a compiler bug, and there's nothing you can do about it, unless you are lucky enough to find a slightly different way of writing the same source code that doesn't crash. The segfault doesn't necessarily indicate anything wrong with your code.


All you can do is submit a bug report ASAP, and use whatever ugly workaround you can come up with, until a new version of the compiler is released.


I suggest you give Xcode 8.2 beta 2 a try. You won't be able to release the app until 8.2 is officially released, but it shouldn't be very long until it is.


Note that, in theory, you can download a newer Swift toolchain from swift.org and use it in Xcode 8.1, but I don't know how well this works in practice. Alternatively, you can try going back to an older Xcode and/or toolchain to avoid the problem.


If none of that is useful, then you should perhaps go to the discussion groups on swift.org and ask about the problem there. You might get a suggestion for cleaner workaround, or help using a newer Swift in 8.1.

Yeah, I intend to file a bug as soon as I can isolate the degree of complexity that triggers the issue. I've already tried various trivial "toy" structures and they don't cause the segfaults, so it must be something related to the overall complexity of the code in-situ.


In the mean-time, my work-around has unblocked me.