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-13247] Crash when using enum case as protocol witness #55687

Closed
theblixguy opened this issue Jul 18, 2020 · 2 comments
Closed

[SR-13247] Crash when using enum case as protocol witness #55687

theblixguy opened this issue Jul 18, 2020 · 2 comments
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 run-time crash Bug → crash: Swift code crashed during execution

Comments

@theblixguy
Copy link
Collaborator

Previous ID SR-13247
Radar None
Original Reporter @theblixguy
Type Bug
Status Resolved
Resolution Done
Environment

Swift version 5.3-dev (LLVM 9437a19, Swift d2f131f)
Target: x86_64-apple-darwin19.5.0

Additional Detail from JIRA
Votes 3
Component/s Compiler
Labels Bug, RunTimeCrash
Assignee None
Priority Medium

md5: d642963c32dd1a1d81246575bc705fa7

relates to:

  • SR-13336 [Beta 2 Regression] JIT session error: Failed to materialize symbols

Issue Description:

The following causes a segmentation fault when running:

protocol EvaluatorAction {}

protocol Evaluating {
  associatedtype Action: EvaluatorAction
  func evaluate(_ action: Action)
}

protocol Action_TextField: EvaluatorAction {
  static func textFieldDidChange(text: String) -> Self
}

class Evaluator: Evaluating {
  enum Action: Action_TextField {
    case textFieldDidChange(text: String)
  }

  func evaluate(_ action: Action) {}
}

let evaluator = Evaluator()
evaluator.evaluate(.textFieldDidChange(text: ""))

When running in JIT, you get the following message:

JIT session error: No symbol covering address 0x0000000000000788

Failed to materialize symbols: { (0x7fcf87c8f410, { _symbolic x, _$s4test10EvaluatingMp, _$s4test9EvaluatorCACycfCTq, _$s4test9EvaluatorC6ActionOAA0bC0AAMc, _$s4test9EvaluatorC6ActionON, _$s4test9EvaluatorC6ActionOMn, _$s4test16Action_TextFieldPAA09EvaluatorB0Tb, _$s4test9EvaluatorCN, _$s4test9EvaluatorC6ActionOMa, ___swift_memcpy16_8, _$s4test9EvaluatorC6ActionO18textFieldDidChangeyAESS_tcAEmF, _$s4test16Action_TextFieldTL, _$s4test10EvaluatingP6ActionAC_AA09EvaluatorC0Tn, _$s4test9EvaluatorCAA10EvaluatingAAMc, _$s4test9EvaluatorC8evaluateyyAC6ActionOFTq, _$s4test9EvaluatorCAA10EvaluatingAAWP, _$s4test9EvaluatorCMn, _$s4test10EvaluatingTL, _symbolic SS4text_t, _$s4test9EvaluatorC8evaluateyyAC6ActionOF, _$s6Action4test10EvaluatingPTl, _symbolic $s4test16Action_TextFieldP, _associated conformance 4test9EvaluatorCAA10EvaluatingAA6ActionAaDP_AA0bD0, _$s4test16Action_TextFieldMp, _$s4test15EvaluatorActionMp, _symbolic 6Action_____Qz 4test10EvaluatingP, _$s4test9evaluatorAA9EvaluatorCvp, _$s4test9EvaluatorCfd, _$s4test9EvaluatorC6ActionOAA0C10_TextFieldAAMc, _$s4test9EvaluatorCMm, _symbolic _____ 4test9EvaluatorC6ActionO, _$s4test9EvaluatorC6ActionOAA0bC0AAWP, _$s4test9EvaluatorC6ActionOAA0C10_TextFieldAAWP, _main, _$s4test9EvaluatorCACycfc, _symbolic $s4test15EvaluatorActionP, _symbolic $s4test10EvaluatingP, _symbolic _____ 4test9EvaluatorC, _$s4test9EvaluatorCACycfC, _$s4testMXM, _$s4test9EvaluatorCMa, _$s4test9EvaluatorCfD }) }

Strangely, renaming some things fixes the crash. For example, if you rename Evaluating to something that has less characters, like P then it doesn't crash.

@swift-ci
Copy link
Collaborator

Comment by Stephen Emery Cotner (JIRA)

Thanks very much for reporting this bug, Suyash. I'm glad my Evaluating experiment is making the rounds!

I'm afraid there might be important context missing, though.

Here is the complete example I originally posted on Twitter (cleaned up a little), which will crash in a playground. There are two essential things to notice:

  1. The "view" instance only knows its evaluator by a protocol, not by the concrete type.

  2. The type() method interpolates the string in the text it sends to the evaluator.

This results in the error:

error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.

Here's the code:

protocol Evaluating {
    associatedtype Action: EvaluatorAction
    func evaluate(_ action: Action)
}

protocol EvaluatorAction {}

protocol Evaluating_TextField: Evaluating where Action: Action_TextField {}

protocol Action_TextField: EvaluatorAction {
    static func textFieldDidChange(text: String) -> Self
}

class Evaluator: Evaluating, Evaluating_TextField {
    enum Action: Action_TextField {
        case textFieldDidChange(text: String)
    }
    
    func evaluate(_ action: Action) {
        switch action {
        case .textFieldDidChange(let text):
            print("text: \(text)")
        }
    }
}

struct SomethingLikeAView<E: Evaluating_TextField> {
    let evaluator: E
    
    init(evaluator: E) {
        self.evaluator = evaluator
    }
    
    func type() {
        let string: String = "thioahsdlfkjds lfjoidsjflkjds flkjds lkf aslkjfldsjf lkjsd flkjsd fl;kjsd a;fklj asdfkljdsa"
        evaluator.evaluate(.textFieldDidChange(text: "\(string)")) // note: this is "\(string)", not the string itself
    }
}

let evaluator = Evaluator()
let view = SomethingLikeAView(evaluator: evaluator)
view.type()

I'm not very knowledgeable about heap allocations, but as far as I can tell, the string is freed from the heap as soon as it's added. When it comes time to print out the interpolated string, it's already gone.

This problem does not happen if an evaluator is referred to by its concrete type.

For instance, if you replace the line:

struct SomethingLikeAView<E: Evaluating_TextField> {

with:

struct SomethingLikeAView<E: Evaluator> {

then there is no crash.

It is only when the evaluator is known by a protocol — when an enum case is really acting as a protocol witness — that we see this problem.

@slavapestov
Copy link
Member

I believe @jckarter fixed this a while back: #35838

@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 run-time crash Bug → crash: Swift code crashed during execution
Projects
None yet
Development

No branches or pull requests

4 participants