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

Swift Embedded: Unexpected crash during class instance deallocation #74697

Closed
tyetrask opened this issue Jun 25, 2024 · 2 comments · Fixed by #76231
Closed

Swift Embedded: Unexpected crash during class instance deallocation #74697

tyetrask opened this issue Jun 25, 2024 · 2 comments · Fixed by #76231
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. embedded Embedded Swift

Comments

@tyetrask
Copy link

tyetrask commented Jun 25, 2024

Description

(Hello, this is my first issue in swiftlang/swift so I apologize in advance if I've put it somewhere incorrect or made mistakes/omissions in the report! @rauhul suggested creating this issue for review and tagging him and @kubamracek. Thank you for looking!)

Description

Using a class that contains a struct (with certain properties) within a Playdate game built with Swift Embedded, the game crashes when that class instance is deallocated.

System Crash Report

(Pease let me know if there are other sections from the report I shouldinclude!)

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_PROTECTION_FAILURE at 0x000000016b363fe0
Exception Codes:       0x0000000000000002, 0x000000016b363fe0

Termination Reason:    Namespace SIGNAL, Code 11 Segmentation fault: 11
Terminating Process:   exc handler [25298]

VM Region Info: 0x16b363fe0 is in 0x167b60000-0x16b364000;  bytes after start: 58736608  bytes before end: 31
      REGION TYPE                    START - END         [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL
      MALLOC_MEDIUM               158000000-160000000    [128.0M] rw-/rwx SM=PRV  
      GAP OF 0x7b60000 BYTES
--->  STACK GUARD                 167b60000-16b364000    [ 56.0M] ---/rwx SM=NUL  stack guard for thread 0
      Stack                       16b364000-16bb60000    [ 8176K] rw-/rwx SM=SHM  thread 0

Thread 0 Crashed::  Dispatch queue: com.apple.main-thread
0   pdex.dylib                    	       0x10dfcbd04 SceneWithThing.__deallocating_deinit + 0
1   pdex.dylib                    	       0x10dfcbe40 swift_release(object:) + 76
2   pdex.dylib                    	       0x10dfcbd4c SceneWithThing.__deallocating_deinit + 72
3   pdex.dylib                    	       0x10dfcbe40 swift_release(object:) + 76
4   pdex.dylib                    	       0x10dfcbd4c SceneWithThing.__deallocating_deinit + 72
5   pdex.dylib                    	       0x10dfcbe40 swift_release(object:) + 76
6   pdex.dylib                    	       0x10dfcbd4c SceneWithThing.__deallocating_deinit + 72
7   pdex.dylib                    	       0x10dfcbe40 swift_release(object:) + 76
8   pdex.dylib                    	       0x10dfcbd4c SceneWithThing.__deallocating_deinit + 72
9   pdex.dylib                    	       0x10dfcbe40 swift_release(object:) + 76
10  pdex.dylib                    	       0x10dfcbd4c SceneWithThing.__deallocating_deinit + 72
11  pdex.dylib                    	       0x10dfcbe40 swift_release(object:) + 76
12  pdex.dylib                    	       0x10dfcbd4c SceneWithThing.__deallocating_deinit + 72
13  pdex.dylib                    	       0x10dfcbe40 swift_release(object:) + 76
14  pdex.dylib                    	       0x10dfcbd4c SceneWithThing.__deallocating_deinit + 72

(... many repeats omitted for space ...)

497 pdex.dylib                    	       0x10dfcbe40 swift_release(object:) + 76
498 pdex.dylib                    	       0x10dfcbd4c SceneWithThing.__deallocating_deinit + 72
499 pdex.dylib                    	       0x10dfcbe40 swift_release(object:) + 76
500 pdex.dylib                    	       0x10dfcbd4c SceneWithThing.__deallocating_deinit + 72
501 pdex.dylib                    	       0x10dfcbe40 swift_release(object:) + 76
502 pdex.dylib                    	       0x10dfcbd4c SceneWithThing.__deallocating_deinit + 72
503 pdex.dylib                    	       0x10dfcbe40 swift_release(object:) + 76
504 pdex.dylib                    	       0x10dfcbd4c SceneWithThing.__deallocating_deinit + 72
505 pdex.dylib                    	       0x10dfcbe40 swift_release(object:) + 76
506 pdex.dylib                    	       0x10dfcbd4c SceneWithThing.__deallocating_deinit + 72
507 pdex.dylib                    	       0x10dfcbe40 swift_release(object:) + 76
508 pdex.dylib                    	       0x10dfcbd4c SceneWithThing.__deallocating_deinit + 72
509 pdex.dylib                    	       0x10dfcbe40 swift_release(object:) + 76
510 pdex.dylib                    	       0x10dfcbd4c SceneWithThing.__deallocating_deinit + 72

Thread 1:
0   libsystem_pthread.dylib       	       0x1913fdd20 start_wqthread + 0

Thread 2:
0   libsystem_pthread.dylib       	       0x1913fdd20 start_wqthread + 0

Reproduction

(⚠️ EDIT June 25th, 1:10pm Pacific: Updated example to use swift-playdate-examples instead, as it removes a dependency on a different third-party library.)

Unfortunately, I don't yet have an individual snippet of Swift code that reproduces this issue without involving a Playdate game. I've tried to make this happen outside of a game still using Swift Embedded but haven't found something that crashes yet. I'll keep working on that and post an update here if/once I have something.

(This, of course, suggests the issue might not be with Swift Embedded- I'm mentioning it in case it is, as the conditions that cause it (and those that 'prevent' it) are fairly odd and are almost completely using 'plain' Swift types. All that said, if this issue should be closed for that reason, I fully understand!)

  1. Clone repository at the reproduction-deinit-crash branch: https://github.com/tyetrask/swift-playdate-examples/tree/reproduction-deinit-crash
  2. Ensure the Playdate Simulator (2.5.0 a.k.a latest) is installed
  3. Open Examples/MyGame in XCode
  4. Build and run
  5. Wait approximately 2.5 seconds for the first crash

(Copying the contents of Game.swift from the branch here as well:)

import Playdate

// Ways to 'prevent' crash:
// 1. Change Thing from struct to class
// 2. Remove either of the two String properties from Thing struct
// 3. Remove currentThing from SceneWithThing

struct Thing {
    let id: String
    let name: String
    let length: Int
    
    init(id: String, name: String, length: Int) {
        self.id = id
        self.name = name
        self.length = length
    }
}

class SceneBase {
    func onSceneUpdate(deltaTime: Float) -> Void {}
}

class SceneWithThing: SceneBase {
    var currentThing: Thing = Thing(id: "A", name: "Cool Thing", length: 42)
    var totalElapsed: Float = 0.0
    
    override func onSceneUpdate(deltaTime: Float) {
        totalElapsed += deltaTime
        Graphics.fillRect(x: 0, y: 0, width: 400, height: 240, color: 1)
        Graphics.fillRect(x: 20, y: 140, width: CInt(totalElapsed * 10.0), height: 50, color: 0)
    }
}

struct Game {
    var current: SceneBase
    var lastElapsedTime: Float = 0
    var switchSceneTimer: Float = 0
    
    init() {
        // Setup the device before any other operations.
        srand(System.getSecondsSinceEpoch(milliseconds: nil))
        Display.setRefreshRate(rate: 50)
        
        current = SceneWithThing()
    }
    
    mutating func updateGame() {
        let elapsedTime = System.elapsedTime
        let deltaTime = elapsedTime - lastElapsedTime
        lastElapsedTime = elapsedTime
        
        current.onSceneUpdate(deltaTime: deltaTime)
        
        switchSceneTimer += deltaTime
        if switchSceneTimer > 2.5 {
            // Crash happens during the next line:
            current = SceneWithThing()
            switchSceneTimer = 0
        }
        
        System.drawFPS(x: 0, y: 0)
    }
}

Expected behavior

The app/Playdate Simulator should not crash 😄.

Environment

Apple Swift version 6.0-dev (LLVM 57177aa1b91540b, Swift 8be6286)
Target: arm64-apple-macosx14.0

(swift-DEVELOPMENT-SNAPSHOT-2024-06-13-a.xctoolchain, latest as of posting this issue)

Additional information

No response

@tyetrask tyetrask added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels labels Jun 25, 2024
@rauhul rauhul added the embedded Embedded Swift label Jun 25, 2024
@hborla hborla removed the triage needed This issue needs more specific labels label Jul 14, 2024
paulstraw added a commit to paulstraw/pdk-exc-bad-access that referenced this issue Aug 31, 2024
@finnvoor
Copy link

finnvoor commented Sep 1, 2024

Some more info:

Minimal repro (no Playdate dependencies)

// foo.swift

struct Foo {
    let foo: String
    let bar: String
}

class Bar {}
class SubBar: Bar {
    var foo = Foo(foo: "", bar: "")
}

var bar: SubBar? = SubBar()
bar = nil

swiftc foo.swift -wmo -enable-experimental-feature Embedded -O

Crashes here in EmbeddedShims:

(*(HeapObjectDestroyer *)destroy_location)(object);

lldb:

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x16f603ff0)
    frame #0: 0x0000000100003e18 foo`Swift.swift_bridgeObjectRelease(object: Builtin.RawPointer) -> ()
foo`Swift.swift_bridgeObjectRelease(object: Builtin.RawPointer) -> ():
->  0x100003e18 <+0>:  stp    x20, x19, [sp, #-0x20]!
    0x100003e1c <+4>:  stp    x29, x30, [sp, #0x10]
    0x100003e20 <+8>:  add    x29, sp, #0x10
    0x100003e24 <+12>: tbnz   x0, #0x3f, 0x100003e68 ; <+80>

latest toolchain

Apple Swift version 6.1-dev (LLVM fe0f467028c23cf, Swift 406b8bd8921b5dc)
Target: arm64-apple-macosx15.0

cc @kubamracek @rauhul

@kubamracek
Copy link
Contributor

Can reproduce.

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. embedded Embedded Swift
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants