stephencelis / SQLite.swift

A type-safe, Swift-language layer over SQLite3.
MIT License
9.67k stars 1.56k forks source link

Crashes when Calling Sync on a DispatchQueue in a Transaction with a Statement Inside #929

Open ghost opened 5 years ago

ghost commented 5 years ago

If you call sync on a DispatchQueue (and run a statement inside the closure) inside of a transaction, SQLite.swift will have called sync twice on the same DispatchQueue and therefore crash the program.

Internally, SQLite.swift checks the current executing DispatchQueue to find if it contains a context value made out of the bits of the Connection to figure out if it should call sync on it or not. Sync being called on a DispatchQueue changes out the queue associated with the current execution context, but continues running code on the same call stack.

func test() {
    let connection = try! Connection()

    let dispatchQueue = DispatchQueue(label: "Test")

    try! connection.transaction {
        dispatchQueue.sync {
            // Crash
            try! connection.execute(".")
        }
    }

    let wait = 1 + 1
}
vincekinyops commented 5 years ago

I also see this in my crash logs stack trace when I submitted my app on App Store and they reviewed it. Please shed some light on this issue.

nobre84 commented 4 years ago

Any news on this? I saw something some crash logs that brought me here and it might be related

jberkel commented 3 years ago

Related: #813, #365, #259