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

A wired crash on sqlite3_step #1738

Closed
Josscii opened this issue Mar 3, 2025 · 8 comments
Closed

A wired crash on sqlite3_step #1738

Josscii opened this issue Mar 3, 2025 · 8 comments
Labels
invalid or off-topic Not about GRDB, or does not contain any useful information

Comments

@Josscii
Copy link

Josscii commented Mar 3, 2025

    func migrateWordRank() async {
        do {
            let context = PersistenceController.shared.container.newBackgroundContext()
            let dbHelper = WordDBHelper.shared

            try context.performAndWait {
                let request = WordEntity.fetchRequest()
                request.sortDescriptors = [NSSortDescriptor(keyPath: \WordEntity.timestamp, ascending: true)]
                request.predicate = NSPredicate(format: "rank <= 0")
                let words = try context.fetch(request)

                for word in words {
                    if let rank = dbHelper.getRank(word: word.viewText, lang: word.lang) {
                        word.rank = Int64(rank)
                    }
                }

                try context.save()
            }
        } catch {
            print("migrateWordRank error", error)
        }
    }
@MainActor
class WordDBHelper {
    static let shared = WordDBHelper()

    private var dbQueue: DatabaseQueue?

    private init() {
        let dbPath = Bundle.main.path(forResource: "words", ofType: "sqlite")!
        dbQueue = try? DatabaseQueue(path: dbPath)
    }

    func getRank(word: String, lang: String?) -> Int? {
        guard let dbQueue = dbQueue else { return nil }

        let sql = "SELECT rank FROM words WHERE word = ? COLLATE NOCASE"

        if let wordRank = try? dbQueue.read({ db in
            try Int.fetchOne(db, sql: sql, arguments: [word])
        }) {
            return wordRank
        }

        let lemma = word.canLemmatized ? word.lemmatized(lang: lang) : word

        if lemma != word, let lemmaRank = try? dbQueue.read({ db in
            try Int.fetchOne(db, sql: sql, arguments: [lemma])
        }) {
            return lemmaRank
        }

        return nil
    }
}
Image

hi, I can't figure out why this crash here, the stack trace is not that helpful, would somebody help?

@groue
Copy link
Owner

groue commented Mar 3, 2025

I can't figure out why this crash here

Nobody can. There's no visible crash in your report.

From now on, please fill in the issue template when you submit an issue here. Consider providing a minimal reproducible example.

God helps those who help themselves

@groue groue closed this as completed Mar 3, 2025
@groue groue added the invalid or off-topic Not about GRDB, or does not contain any useful information label Mar 3, 2025
@Josscii
Copy link
Author

Josscii commented Mar 3, 2025

Sorry, I thought it was a GRDB related concurency issue, cause it happens when I add this feature. In the stack trace it did crash at here:

#11	0x00000001031d312c in closure #1 in closure #1 in closure #1 in DatabasePool.barrierWriteWithoutTransaction<A>(_:)

While I use DatabaseQueue, not even use DatabasePool.

I use the read method to access database, I thought it was thread safe, but it crashed, it it a random crash, not every device encouter it, so I don't have example.

@groue
Copy link
Owner

groue commented Mar 3, 2025

I'm sorry @Josscii, but you do not provide any useful information. You do not even provide any error message or anything. This makes it completely impossible to help you. Your first task, when you open an issue about a "crash", is to show that crash. Look for an error message, code, whatever. Find something.

@Josscii
Copy link
Author

Josscii commented Mar 3, 2025

here is my crash:

Exception Type:  EXC_CRASH (SIGKILL)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Termination Reason: RUNNINGBOARD 0xdead10cc 

Triggered by Thread:  0


Thread 0 Crashed:
0   libsqlite3.dylib              	0x00000001c4a6d6fc getCellInfo + 60 (sqlite3.c:81665)
1   libsqlite3.dylib              	0x00000001c4a02628 sqlite3VdbeExec + 30388 (sqlite3.c:102967)
2   libsqlite3.dylib              	0x00000001c49fa6b4 sqlite3_step + 960 (sqlite3.c:97900)
3   Aisten                        	0x000000010322c428 Statement.step<A>(_:) + 72 (Statement.swift:615)
4   Aisten                        	0x0000000103227bcc DatabaseCursor.next() + 300 (Statement.swift:751)
5   Aisten                        	0x0000000103230d10 static DatabaseValueConvertible<>.fetchOne(_:arguments:adapter:) + 340 (StatementColumnConvertible.swift:373)
6   Aisten                        	0x0000000103231eac static DatabaseValueConvertible<>.fetchOne<A>(_:_:) + 136 (StatementColumnConvertible.swift:674)
7   Aisten                        	0x0000000103230f14 static DatabaseValueConvertible<>.fetchOne(_:sql:arguments:adapter:) + 312 (StatementColumnConvertible.swift:519)
8   Aisten                        	0x00000001028cccc8 closure #1 in WordDBHelper.getRank(word:lang:) + 264
9   Aisten                        	0x00000001028ccbb8 closure #2 in WordDBHelper.getRank(word:lang:) + 12
10  Aisten                        	0x00000001026708d4 partial apply for closure #2 in WordDBHelper.getRank(word:lang:) + 20 (/<compiler-generated>:0)
11  Aisten                        	0x00000001031d312c closure #1 in closure #1 in closure #1 in DatabasePool.barrierWriteWithoutTransaction<A>(_:) + 8 (DatabasePool.swift:830)
12  Aisten                        	0x00000001031d312c partial apply for closure #1 in closure #1 in DatabaseQueue.read<A>(_:) + 28 (/<compiler-generated>:0)
13  Aisten                        	0x00000001031d5f80 partial apply for closure #1 in closure #1 in DatabaseQueue.read<A>(_:) + 12
14  Aisten                        	0x00000001031b6ff8 closure #1 in closure #1 in Database.isolated<A>(readOnly:_:) + 112
15  Aisten                        	0x00000001031c48c0 partial apply for closure #2 in Database.isolated<A>(readOnly:_:) + 20 (/<compiler-generated>:0)
16  Aisten                        	0x00000001031c49b0 partial apply for closure #1 in closure #1 in Database.isolated<A>(readOnly:_:) + 12
17  Aisten                        	0x00000001031b4e54 closure #1 in Database.inSavepoint(_:) + 12 (Database.swift:1561)
18  Aisten                        	0x00000001031b4e54 specialized Database.inTransaction(_:_:) + 92 (Database.swift:1443)
19  Aisten                        	0x00000001031b18b8 Database.inSavepoint(_:) + 252 (Database.swift:1561)
20  Aisten                        	0x00000001031b6df8 closure #1 in Database.isolated<A>(readOnly:_:) + 28 (Database.swift:1499)
21  Aisten                        	0x00000001031b6df8 specialized throwingFirstError<A>(execute:finally:) + 28 (Utils.swift:107)
22  Aisten                        	0x00000001031b6df8 specialized Database.readOnly<A>(_:) + 52 (Database.swift:866)
23  Aisten                        	0x00000001031b6df8 Database.isolated<A>(readOnly:_:) + 264 (Database.swift:1498)
24  Aisten                        	0x00000001031d5e08 partial apply for closure #1 in DatabaseQueue.read<A>(_:) + 56
25  Aisten                        	0x00000001031d5da4 partial apply for closure #1 in DatabaseQueue.read<A>(_:) + 20
26  Aisten                        	0x0000000103225544 closure #1 in SerializedDatabase.sync<A>(_:) + 44 (SerializedDatabase.swift:127)
27  Aisten                        	0x0000000103227490 partial apply for closure #1 in SerializedDatabase.sync<A>(_:) + 20 (/<compiler-generated>:0)
28  libswiftDispatch.dylib        	0x000000019fc69dd4 partial apply for thunk for @callee_guaranteed () -> (@out A, @error @owned Error) + 28 (<compiler-generated>:0)
29  libswiftDispatch.dylib        	0x000000019fc69db0 thunk for @callee_guaranteed () -> (@out A, @error @owned Error)partial apply + 16 (:-1)
30  libswiftDispatch.dylib        	0x000000019fc69d18 closure #1 in closure #1 in OS_dispatch_queue._syncHelper<A>(fn:execute:rescue:) + 192 (Queue.swift:403)
31  libswiftDispatch.dylib        	0x000000019fc69c3c partial apply for thunk for @callee_guaranteed () -> () + 28 (<compiler-generated>:0)
32  libswiftDispatch.dylib        	0x000000019fc69c14 thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0)
33  libdispatch.dylib             	0x000000019e60afa8 _dispatch_client_callout + 20 (object.m:576)
34  libdispatch.dylib             	0x000000019e61a7fc _dispatch_lane_barrier_sync_invoke_and_complete + 56 (queue.c:1104)
35  libswiftDispatch.dylib        	0x000000019fc6b6b0 implicit closure #2 in implicit closure #1 in OS_dispatch_queue.asyncAndWait<A>(execute:) + 192 (:-1)
36  libswiftDispatch.dylib        	0x000000019fc6b5e8 partial apply for implicit closure #2 in implicit closure #1 in OS_dispatch_queue.sync<A>(execute:) + 76 (<compiler-generated>:0)
37  libswiftDispatch.dylib        	0x000000019fc6b468 OS_dispatch_queue._syncHelper<A>(fn:execute:rescue:) + 404 (Queue.swift:400)
38  libswiftDispatch.dylib        	0x000000019fc6b2a4 OS_dispatch_queue.asyncAndWait<A>(execute:) + 140 (:-1)
39  libswiftDispatch.dylib        	0x000000019fc6b210 OS_dispatch_queue.sync<A>(execute:) + 64 (:-1)
40  Aisten                        	0x0000000103223134 SerializedDatabase.sync<A>(_:) + 352 (SerializedDatabase.swift:125)
41  Aisten                        	0x00000001031d4614 DatabaseQueue.read<A>(_:) + 44 (DatabaseQueue.swift:229)
42  Aisten                        	0x000000010266ff70 WordDBHelper.getRank(word:lang:) + 136 (WordDBHelper.swift:49)
43  Aisten                        	0x000000010266ff70 closure #1 in CloudKitSyncNotifier.migrateWordRank() + 816 (CloudKitSyncNotifier.swift:121)
44  Aisten                        	0x00000001026708a4 partial apply for closure #1 in CloudKitSyncNotifier.migrateWordRank() + 16 (/<compiler-generated>:0)
45  CoreData                      	0x000000019e89ae1c thunk for @callee_guaranteed () -> (@out A, @error @owned Error) + 28 (<compiler-generated>:0)
46  CoreData                      	0x000000019e89adf8 partial apply for thunk for @callee_guaranteed () -> (@out A, @error @owned Error) + 24 (<compiler-generated>:0)
47  CoreData                      	0x000000019e89ad30 closure #1 in closure #1 in NSManagedObjectContext._rethrowsHelper_performAndWait<A>(fn:execute:rescue:) + 192 (NSManagedObjectContext.swift:143)
48  CoreData                      	0x000000019e89ac54 thunk for @callee_guaranteed () -> () + 28 (<compiler-generated>:0)
49  CoreData                      	0x000000019e89abfc thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0)
50  CoreData                      	0x000000019e874a7c developerSubmittedBlockToNSManagedObjectContextPerform + 476 (NSManagedObjectContext.m:3984)
51  libdispatch.dylib             	0x000000019e60afa8 _dispatch_client_callout + 20 (object.m:576)
52  libdispatch.dylib             	0x000000019e61a7fc _dispatch_lane_barrier_sync_invoke_and_complete + 56 (queue.c:1104)
53  CoreData                      	0x000000019e8c7dc0 -[NSManagedObjectContext performBlockAndWait:] + 308 (NSManagedObjectContext.m:4108)
54  CoreData                      	0x000000019e8c7b34 NSManagedObjectContext.performAndWait<A>(_:) + 556 (NSManagedObjectContext.swift:207)
55  Aisten                        	0x00000001026707bc specialized CloudKitSyncNotifier.migrateWordRank() + 124 (CloudKitSyncNotifier.swift:114)
56  Aisten                        	0x000000010266f305 CloudKitSyncNotifier.migrateIfNeeded() + 1 (CloudKitSyncNotifier.swift:64)
57  Aisten                        	0x000000010266ef8d closure #1 in PodcastStarManager.starredPodcastIds.didset + 1 (CloudKitSyncNotifier.swift:57)
58  Aisten                        	0x000000010264c4c9 partial apply for specialized thunk for @escaping @isolated(any) @callee_guaranteed @async () -> (@out A) + 1 (/<compiler-generated>:0)
59  Aisten                        	0x0000000102aa4129 specialized thunk for @escaping @isolated(any) @callee_guaranteed @async () -> (@out A) + 1
60  Aisten                        	0x000000010264c639 partial apply for closure #1 in AudioTranscriber.startTask(task:) + 1
61  libswift_Concurrency.dylib    	0x00000001a21a3e39 completeTaskWithClosure(swift::AsyncContext*, swift::SwiftError*) + 1 (Task.cpp:497)

I see the terminal reason is RUNNINGBOARD 0xdead10cc, it seems I encounter deadlock, it may be I use some block method in async function, I'll try figure out myself.

thanks for your time.

@groue
Copy link
Owner

groue commented Mar 3, 2025

I see the terminal reason is RUNNINGBOARD 0xdead10cc, it seems I encounter deadlock, it may be I use some block method in async function, I'll try figure out myself.

Oh, 0xdead10cc.

Please have a look at a recent discussion about it, starting from this comment.

You'll find other GRDB issues and discussions about 0xdead10cc if you perform a search, but I recommend starting from the above link, and following advice.

@Josscii
Copy link
Author

Josscii commented Mar 3, 2025

Thanks for your information.

But my database file is shipped with my app bundle, I don't share it across other process or something, it only has one connection.

@groue
Copy link
Owner

groue commented Mar 3, 2025

Please check Apple documentation for 0xDEAD10CC: https://developer.apple.com/documentation/xcode/sigkill

@Josscii
Copy link
Author

Josscii commented Mar 3, 2025

THANKS!

I think I know what may cause this problem and how to probably solve this crash now.

I'll try extend the background excution time when try to do migrations which access the database.

Thank again, really sorry for my bad at issue reporting, will improve this next time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid or off-topic Not about GRDB, or does not contain any useful information
Projects
None yet
Development

No branches or pull requests

2 participants