Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-8054] Failure during MergeSwiftModule when UIView subclass implements init() #50587

Closed
swift-ci opened this issue Jun 21, 2018 · 16 comments
Closed
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself crash Bug: A crash, i.e., an abnormal termination of software serialization Area → compiler: Serialization & deserialization

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-8054
Radar rdar://problem/41331997
Original Reporter amro (JIRA User)
Type Bug
Status Closed
Resolution Cannot Reproduce

Attachment: Download

Environment

Xcode 10 beta 2, Swift 4 compatibility❓ mode. This worked fine in Xcode 10 beta 1.

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, CompilerCrash, Serialization
Assignee None
Priority Medium

md5: f70b0879ad67b16eb37d0c1d02f59109

relates to:

  • SR-9066 Abort trap 6 While deserializing SIL vtable

Issue Description:

MergeSwiftModule fails on a UIView subclass that implements init() instead of init(frame: CGRect). The error is "could not find 'init()' in parent class."

Apologies in advance as I cannot provide the project and have not yet been able to repro in a sample project. Hopefully the log snippet is helpful.

The good news is the full diagnostic output is clear and points one to the problematic file so I was able to work around this issue.

MergeSwiftModule normal arm64
<snip>
<unknown>:0: error: fatal error encountered while reading from module 'T1Twitter'; please file a bug report with your project and the crash log
*** DESERIALIZATION FAILURE (please include this section in any bug report) ***
could not find 'init()' in parent class
0 swift 0x000000010f1d4a9a PrintStackTraceSignalHandler(void*) + 42
1 swift 0x000000010f1d3ea6 SignalHandler(int) + 966
2 libsystem_platform.dylib 0x00007fff6ca7af5a _sigtramp + 26
3 libsystem_platform.dylib 0x000000011aba42c4 _sigtramp + 2920452996
4 libsystem_c.dylib 0x00007fff6c8181ae abort + 127
5 swift 0x000000010c68e80b swift::ModuleFile::fatal(llvm::Error) + 1915
6 swift 0x000000010c6c6493 getSILDeclRef(swift::ModuleFile*, llvm::ArrayRef<unsigned long long>, unsigned int&) + 307
7 swift 0x000000010c6b3273 swift::SILDeserializer::readSILInstruction(swift::SILFunction*, swift::SILBasicBlock*, swift::SILBuilder&, unsigned int, llvm::SmallVectorImpl<unsigned long long>&) + 1235
8 swift 0x000000010c6b256f swift::SILDeserializer::readSILFunction(llvm::PointerEmbeddedInt<unsigned int, 31>, swift::SILFunction*, llvm::StringRef, bool, bool) + 6591
9 swift 0x000000010c6c823d swift::SILDeserializer::getAllSILFunctions() + 893
10 swift 0x000000010c76e62a swift::SerializedSILLoader::getAllForModule(swift::Identifier, swift::FileUnit*) + 170
11 swift 0x000000010b4c586e performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 34750
12 swift 0x000000010b4b9bbf swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 7839
13 swift 0x000000010b463768 main + 13144
14 libdyld.dylib 0x00007fff6c76c015 start + 1
15 libdyld.dylib 0x0000000000000058 start + 2475245636
Stack dump:
@belkadan
Copy link
Contributor

That's a new one. Is there any more information you can share? Anything from the "stack dump" section, or perhaps the definition of the problematic subclass initializer?

@belkadan
Copy link
Contributor

@swift-ci create

@swift-ci
Copy link
Collaborator Author

Comment by Amro Mousa (JIRA)

Here's an example of a problematic initializer definition:

class SingleAutoplayableManagerDebugView: UIView {
    init() {
        super.init(frame: .zero)
    }
    ...
}

Some cases, like this one, are just this simple (really don't need to be there are all...). However, in other cases the initializers initialize subviews or other instance variables as well.

I can't say I'm familiar with the parts of our codebase triggering this.

Give me a bit to repro and get the full error text for you.

@swift-ci
Copy link
Collaborator Author

Comment by Amro Mousa (JIRA)

Full error message text attached as requested

error.txt

@belkadan
Copy link
Contributor

While deserializing SIL function "$S9T1Twitter16MomentFollowViewCACycfC"

$S9T1Twitter16MomentFollowViewCACycfC ---> T1Twitter.MomentFollowView.__allocating_init() -> T1Twitter.MomentFollowView

Hm. Since we have a specific example here, can you confirm that MomentFollowView directly subclasses UIView, and therefore shouldn't be referencing init()?

@swift-ci
Copy link
Collaborator Author

Comment by Amro Mousa (JIRA)

Yes, that view subclassed UIView directly.

Showing my ignorance here: Is init() marked unavailable on UIView? I don't see that in the header. I realize it's odd, but I'd expect to either get some sort of error in the editor or have it work since init ought to call init(frame:) w/ .zero.

@belkadan
Copy link
Contributor

It's not marked specially at all, but that makes it a convenience initializer, not a designated initializer, and that means it's not safe to call from a subclass. (What if you implemented init() but also init(frame:)?)

@swift-ci
Copy link
Collaborator Author

Comment by Amro Mousa (JIRA)

I see. Sure, that'd be fine. I ended up changing the offending classes to implement only init(frame:). We didn't specifically need init(). I'm honestly not sure why that pattern was adopted. Thank you.

I think the issue of the way the compiler failed stands. The improved logging was noticed and appreciated. If I could suggest an improvement there it would be to show the failing file name above the stack dump section (maybe replace the "<unknown>:0" bit) since it's the critical piece of information one would need to work around some other error similar to this.

@belkadan
Copy link
Contributor

This error message is coming from AST deserialization logic: for some reason, it thinks the init() on your subclass is trying to override an init() on UIView.

For the example you gave above, or for MomentFollowView, are there any attributes or modifiers on the initializer that you left out of the simplified form? Anything on the class? And is there a custom implementation of init() on UIView in an extension somewhere?

@swift-ci
Copy link
Collaborator Author

Comment by Amro Mousa (JIRA)

Thanks for your patience. I've been traveling and wasn't able to check. The views in question were direct UIView subclasses that attempted to define init() and there's no extension defining an implementation of init(). I'll try to get a repro case and close this ticket if I can't in the next few days.

@swift-ci
Copy link
Collaborator Author

Comment by Amro Mousa (JIRA)

Thanks for your patience here. I can't repro this in a standalone project and haven't seen it in ours recently so I'm going to close it.

@belkadan
Copy link
Contributor

We haven't been able to track it down either, but you're not the only one hitting it. Hopefully we'll get a reproducible test case soon.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Oct 4, 2018

Comment by Karl Puusepp (JIRA)

We also saw it appear when developing a completely unrelated feature. The only workarounds were either to force whole-module compilation or reorder some of the added sources in the project file.

@belkadan
Copy link
Contributor

belkadan commented Oct 4, 2018

I can totally believe that it's something that subtle. :-( If anyone has a project that they can share in a failing state (either here or at https://bugreport.apple.com) that would be greatly appreciated.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Oct 5, 2018

Comment by Karl Puusepp (JIRA)

Unfortunately I'm not able to share our project, but I have some more findings which hopefully could be of some use.

We use XcodeGen to generate our project files, which sorts target source files alphabetically. A new feature added several UIViewController subtypes into files beginning with an `ADR` prefix, thereby moving them to the top of the sources list.

As soon as any definition in one of those files inherits from UIViewController, UIView or even UIResponder this abort trap occurs (inherting from UIGestureRecognizer for example seems OK). Renaming the files to move them down the list (after regenerating the project) fixes the issue.

We have quite a lot of UIView and UIViewController subtypes that declare a no-argument `init`, but all these other usages have traditionally not caused any issues. But we've also never written view controllers starting with the letter A before.

Xcode 10.0, Swift 4.2, incremental compile mode. I tried creating a simple repro project with this file ordering logic, but it does not trigger the failure. Also happens on 10.1 Beta 2.

@swift-ci
Copy link
Collaborator Author

Comment by Alvar Hansen (JIRA)

@belkadan, we were able to create a project where this error reproduces. I've created a new ticket here: https://bugs.swift.org/browse/SR-9066

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@AnthonyLatsis AnthonyLatsis added the crash Bug: A crash, i.e., an abnormal termination of software label Dec 12, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself crash Bug: A crash, i.e., an abnormal termination of software serialization Area → compiler: Serialization & deserialization
Projects
None yet
Development

No branches or pull requests

3 participants