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-15803] Deep recursion in deinit should not happen #58080

Open
swift-ci opened this issue Feb 1, 2022 · 3 comments
Open

[SR-15803] Deep recursion in deinit should not happen #58080

swift-ci opened this issue Feb 1, 2022 · 3 comments
Labels
ARC Feature: automatic reference counting 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 deinit Feature: deinitializers run-time crash Bug → crash: Swift code crashed during execution

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Feb 1, 2022

Previous ID SR-15803
Radar None
Original Reporter Stefan Springer (JIRA User)
Type Bug
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug
Assignee None
Priority Medium

md5: f656f5102814b117be9fbb97205c3891

Issue Description:

When the removal of the only reference to an item triggers the removal of the only reference to another item and so on, we get a stack overflow of the deinits (could be implicit deinits just created by the compiler for reference counting) when this chain is long enough (depending on how "thick" each deinit is, maybe forum entry https://forums.swift.org/t/a-roadmap-for-improving-swift-performance-predictability-arc-improvements-and-ownership-control/54206 would help with that "thickness" of each item at least). See the example code down below.

See https://github.com/hatzel/swift-simple-queue/blob/6d03e672874a33d05aff4607c3d152bd5e4a2584/Sources/FifoQueue.swift#L8 what people are tying to do to circumvent this problem, but I really think this should not occur at all, my gut feeling is that these nested calls of deinits should be unnecessary (maybe think tail recursion as an analogy). There should be a more clever way to manage the reference counting.

Also see the discussion in the Swift forums: https://forums.swift.org/t/deep-recursion-in-deinit-should-not-happen/54987

(Note that although this ticket might formally count as asking for an improvement, I created the ticket as a bug report because I think the issue is quite serious.)

Example code:

class Chained {
    var next: Chained? = nil
    init() {}
}

print("building...")
var first: Chained? = Chained()
var last = first
//for _ in 1...1_000_000 { // for release mode
for _ in 1...100_000 { // for debug mode
    let next = Chained()
    last?.next = next
    last = next
}
last = nil

print("forgetting references...")
first = nil // Thread 1: EXC_BAD_ACCESS (code=2, address=0x16f603ff0)

print("done")
@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@stefanspringer1
Copy link

@stefanspringer1
Copy link

stefanspringer1 commented Jan 21, 2023

Just tried my code again with Swift 5.7.2, and the problem does not occur anymore. So at least for this simple case the issue is resolved. Maybe some more complex cases could also be resolved, see the mentioned Swift forums topics, e.g. this answer by Joe Groff or this answer by Dario Rexin.

@stefanspringer1
Copy link

See more complex cases there.

@AnthonyLatsis AnthonyLatsis added ARC Feature: automatic reference counting deinit Feature: deinitializers run-time crash Bug → crash: Swift code crashed during execution crash Bug: A crash, i.e., an abnormal termination of software labels Jan 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ARC Feature: automatic reference counting 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 deinit Feature: deinitializers run-time crash Bug → crash: Swift code crashed during execution
Projects
None yet
Development

No branches or pull requests

3 participants