Describe the bug
Our Flutter app crashes on macOS with native sqlite3 memory errors during normal database usage via NativeDatabase.createBackgroundConnection(). We've observed two distinct crash signatures, both on the DartWorker thread (the background isolate), both involving sqlite3_finalize:
- EXC_BAD_ACCESS (KERN_INVALID_ADDRESS) in
sqlite3_finalize
- SIGABRT in
sqlite3VdbeDelete — "pointer being freed was not allocated" (double-free)
Both crashes occur during normal read-heavy usage (scrolling through paginated content that triggers many sequential database queries). The app does NOT use multiple database instances or share the connection across isolates.
Environment
| Component |
Version |
| drift |
2.32.0 |
| sqlite3 |
3.2.0 |
| Flutter |
3.38.x |
| Dart |
3.10.x |
| sqlite3_flutter_libs |
Not used (system SQLite on macOS) |
Affected platforms:
- macOS 26.3.1 (Sequoia) on Apple M2 ARM64
- macOS 12.7.6 (Monterey) on Intel x86_64
Not observed on iOS, Android, or other platforms.
Database connection setup
DatabaseConnection connect() {
return DatabaseConnection.delayed(
Future(() async {
if (Platform.isAndroid) {
sqlite3.tempDirectory = (await getTemporaryDirectory()).path;
}
final dbFile = await databaseFile;
return NativeDatabase.createBackgroundConnection(dbFile);
}),
);
}
Single database instance, no shareAcrossIsolates, no custom setup callback, no readPool. Default configuration.
Crash 1: sqlite3_finalize EXC_BAD_ACCESS
- Device: MacBook Air M2 (ARM64), macOS 26.3.1
- App state: Background
- Context: User browsed paginated book content, navigated away, app went to background. Crash occurred on DartWorker thread during statement finalization.
Thread: DartWorker (crashed)
at sqlite3_finalize +32
at <obfuscated dart frame>
at <obfuscated dart frame>
at <obfuscated dart frame>
at <obfuscated dart frame>
at <obfuscated dart frame>
at <obfuscated dart frame>
at <obfuscated dart frame>
at <obfuscated dart frame>
at _pthread_start
at thread_start
Signal: EXC_BAD_ACCESS (KERN_INVALID_ADDRESS)
Crash 2: sqlite3VdbeDelete SIGABRT (double-free)
- Device: MacBook Air 2017 (x86_64), macOS 12.7.6
- App state: Foreground
- Context: User was rapidly scrolling through paginated content (many sequential read queries). Crash occurred on DartWorker thread.
Thread: DartWorker (crashed)
at __pthread_kill
at pthread_kill
at abort
at malloc_vreport
at malloc_zone_error
at free_large
at sqlite3VdbeDelete +1135
at sqlite3_finalize
at <obfuscated dart frame>
at <obfuscated dart frame>
at <obfuscated dart frame>
at <obfuscated dart frame>
at <obfuscated dart frame>
at <obfuscated dart frame>
at <obfuscated dart frame>
at _pthread_start
at thread_start
Signal: SIGABRT (ABORT)
Crash info: "pointer 0x7f7bb3500000 being freed was not allocated"
Analysis
Both crashes point to memory corruption in prepared statement lifecycle management within the background isolate:
- Crash 1:
sqlite3_finalize attempts to access freed memory (use-after-free on statement handle)
- Crash 2:
sqlite3VdbeDelete (called by sqlite3_finalize) attempts to free memory that was already freed (double-free)
This is low frequency (3 events across 3 users over 90 days) but both occurrences are on macOS using system SQLite (no sqlite3_flutter_libs). The crashes are 100% on the DartWorker thread, confirming they occur inside the background isolate created by createBackgroundConnection.
Possibly relevant: drift 2.28.1 introduced "Cache prepared statements by default" — could cached statement reuse interact poorly with finalization timing?
Expected behavior
sqlite3_finalize should safely finalize prepared statements without memory access violations.
Steps to reproduce
We have not been able to reproduce this locally. The crashes are observed via Firebase Crashlytics on production macOS builds. The usage pattern is:
- Open the app on macOS
- Open paginated content that triggers many sequential read queries
- Rapidly scroll through content (triggering section-change queries)
- Optionally: put the app in background
The crash occurs intermittently during step 3 or 4.
Describe the bug
Our Flutter app crashes on macOS with native sqlite3 memory errors during normal database usage via
NativeDatabase.createBackgroundConnection(). We've observed two distinct crash signatures, both on the DartWorker thread (the background isolate), both involvingsqlite3_finalize:sqlite3_finalizesqlite3VdbeDelete—"pointer being freed was not allocated"(double-free)Both crashes occur during normal read-heavy usage (scrolling through paginated content that triggers many sequential database queries). The app does NOT use multiple database instances or share the connection across isolates.
Environment
Affected platforms:
Not observed on iOS, Android, or other platforms.
Database connection setup
Single database instance, no
shareAcrossIsolates, no customsetupcallback, noreadPool. Default configuration.Crash 1:
sqlite3_finalizeEXC_BAD_ACCESSSignal: EXC_BAD_ACCESS (KERN_INVALID_ADDRESS)
Crash 2:
sqlite3VdbeDeleteSIGABRT (double-free)Signal: SIGABRT (ABORT)
Crash info:
"pointer 0x7f7bb3500000 being freed was not allocated"Analysis
Both crashes point to memory corruption in prepared statement lifecycle management within the background isolate:
sqlite3_finalizeattempts to access freed memory (use-after-free on statement handle)sqlite3VdbeDelete(called bysqlite3_finalize) attempts to free memory that was already freed (double-free)This is low frequency (3 events across 3 users over 90 days) but both occurrences are on macOS using system SQLite (no
sqlite3_flutter_libs). The crashes are 100% on the DartWorker thread, confirming they occur inside the background isolate created bycreateBackgroundConnection.Possibly relevant: drift 2.28.1 introduced "Cache prepared statements by default" — could cached statement reuse interact poorly with finalization timing?
Expected behavior
sqlite3_finalizeshould safely finalize prepared statements without memory access violations.Steps to reproduce
We have not been able to reproduce this locally. The crashes are observed via Firebase Crashlytics on production macOS builds. The usage pattern is:
The crash occurs intermittently during step 3 or 4.