Pin sqlite3_connection_pool 0.2.7; unwind the peer-segfault workarounds - #302
Merged
Conversation
Root cause of the exp 262 release-suite segfault: pubspec.lock is untracked, so while the benchmark peers are pinned exactly, sqlite_async 0.14.4's own sqlite3_connection_pool dep is caret-ranged and floats on every fresh pub get. The suite last passed 2026-07-17, when resolution could only produce 0.2.7; 0.2.8 (Jul 31) refactored pool lifetime management and 0.2.9 (Aug 4) reworked native-port plumbing, and sqlite_async 0.14.4 — published Jul 22, before either existed — drives that code into a use-after-free under concurrent watch load (strlen on a freed string inside pkg_sqlite3_connection_pool_notify_updates, via Dart_PostCObject). Empirical: the exact configuration that crashed four times on 0.2.9 tonight (memory scenario enabled, A11b sqlite_async arm restored) ran the full suite clean on 0.2.7, all crash surfaces exercised (15 sqlite_async arm runs, Memory in all three repeats). With the transitive pinned as an exact dev dependency: - Revert #295: restore the A11b High-Cardinality sqlite_async arm and its test expectations. - Drop --skip-memory from CI's suite run (#297) and from the canonical headline command in RUNNER_INSTRUCTIONS and the experiment skill; the flag itself stays in run_release as an escape hatch. Drop the pin when sqlite_async ships a release built against the new pool contracts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…pin regex The trend-fidelity change (#301) moved the docs layer's benchmark source to cross-repeat aggregate medians, which drifted the large-payload selectBytes pin (0.323 last-repeat -> 0.24 median, past its 20% tolerance) and turned Tests red for every PR. The passage's claim — wrapping selectBytes' result buys nothing because the bytes are already a native-buffer view — does not rest on the number; re-pin it. verify.dart --fix mangled the pin while doing so: its expectation-replace regex anchored on the FIRST '~' in the raw pin, which for this metric sits inside the key itself ('Large payload (~650KB)'), swallowing the key up to the tolerance. Require the matched expectation to be numeric, as the '@' branch already implies by using lastIndexOf. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Root cause of the exp 262 release-suite segfault, found and fixed.
The mechanism:
pubspec.lockis untracked (normal for a package repo), so the exactly-pinned benchmark peers had a blind spot —sqlite_async 0.14.4's ownsqlite3_connection_pool: ^0.2.7floats on every freshpub get. The suite last passed 2026-07-17, when resolution could only produce 0.2.7 (0.2.8 didn't exist until Jul 31; 0.2.9 followed Aug 4 — the day exp 262 documented the crash). 0.2.8 refactored pool lifetime management (rawBox::into_rawhandles, two-phase open) and 0.2.9 reworked native-port plumbing;sqlite_async 0.14.4was published Jul 22, before either existed, and drives the new code into a use-after-free under concurrent watch load —strlenon a freed string insidepkg_sqlite3_connection_pool_notify_updatesviaDart_PostCObject(the notification senderupdate_hook.rsis byte-identical across versions; only the lifetime of what it reads changed).Empirical confirmation: the exact configuration that crashed 4/4 times tonight on 0.2.9 — Memory scenario enabled, A11b sqlite_async arm restored — ran the full 3-repeat suite clean on 0.2.7, every crash surface exercised (15 sqlite_async arm executions, Memory in all three repeats). A 0.2.8 bisect run is in flight to sharpen the upstream report; it doesn't change this pin.
With the transitive pinned (exact dev dependency, alongside the existing peer pins):
sqlite_asyncarm and its test expectations are restored.--skip-memoryremoved from CI's suite run (CI: pass --skip-memory to the Benchmarks (main) suite run #297) and from the canonical headline command in RUNNER_INSTRUCTIONS + the experiment skill. The flag itself stays inrun_release.dartas an escape hatch.Unpin when sqlite_async ships a release built against the new pool contracts (an upstream report with the bisection and crash analysis is drafted separately).
🤖 Generated with Claude Code