Repository navigation
ci: pin the Android emulator to 37.1.11 for the crash harness - #52
Merged
Merged
Conversation
The API 34 job has hung since 2026-10-02. The emulator-runner action installs the latest stable emulator when it is given no build, and 37.2.12.0 (build 16428233) became stable on 2026-10-01. On API 34, runs on 37.1.11.0 (build 15917651) passed 19 of 20 times, the one red being the known first-native "received []" flake. Of the runs on 37.2.12.0 that reached the repeat stage, 10 of 10 hung: QEMU stalls about twelve minutes after boot and the harness dies when adb goes offline. The runner image and the system image are the same on the green and the red runs. Pin the emulator to build 15917651 through EMULATOR_BUILD and the action's emulator-build input, fail the step when the running emulator is another build, and log the system image's revision. Sample the host's memory and disk every 15 seconds, and keep dmesg on failure, in the harness-logs artifact, so a further stall is read from evidence. Nothing is skipped, retried or split: API 34 still runs, still repeats native twenty times and still boots once. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XLy7TiPAxtVjPKEwQ9iwBa
The first run on this branch showed that the pin works and the guard did not. The emulator downloaded and booted as 37.1.11.0, build 15917651, but the guard ran emulator -version, which loads QEMU, and the runner has no libpulse for it, so the step failed before the harness started. The boot itself does not take that path. The guard now matches Pkg.BuildId in the emulator's source.properties as a whole line. The pinned zip carries that file with the build id in it, and the step still fails if the installed emulator is any other build. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XLy7TiPAxtVjPKEwQ9iwBa
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.
Summary
The crash harness's API 34 job has hung since 2026-10-02. The cause is an unpinned emulator:
reactivecircus/android-emulator-runnerinstalls the latest stable Android emulator when it is given noemulator-build, and emulator 37.2.12.0 (build 16428233) went stable on 2026-10-01. The first red run is the next day.Evidence, on API 34:
adb force-stopwith the device offline (exit 255).vbmeta.digest), the AVD config (identical), and the guest (no lmkd kills).What this PR changes, in
.github/workflows/crash-harness.ymlonly:env.EMULATOR_BUILD: "15917651"(37.1.11.0), passed to the action asemulator-build.grep -Fx "Pkg.BuildId=$EMULATOR_BUILD" "$ANDROID_HOME/emulator/source.properties". It fails the step if the installed emulator is another build. It reads the SDK's own record of the build because runningemulator -versionfails on the runner (see Verification).Pkg.Revision.free -m,df -hand the five largest processes by RSS, plusdmesg -Ton failure, both kept in theharness-logsartifact.Nothing else moves: API 34 is not skipped or quarantined, the 20 native repeats stay, the boot is not split, and no run is retried. All actions stay SHA-pinned; values reach
run:blocks throughenv:.Intent
The owner asked: "Fix the otel-zone crash harness emulator hang."
The harness exists to measure native crash capture on a real runtime. Hiding the API 34 job would remove that measurement, so the fix keeps the job and pins the one input that changed underneath it.
Verification
Local:
actionlint,zizmorandyamllintare clean on the workflow. The only zizmor findings, at the pedantic persona, are the three pre-existing${{ env.OTEL_PORT }}uses inrun:lines I did not touch.emulator-linux_x64-15917651.zipdownloads (334378080 bytes) and itsemulator/source.propertiesholdsPkg.Revision=37.1.11andPkg.BuildId=15917651. The guard line exits 0 against that file, and 1 for build 16428233 and for the prefix 1591765.dmesgsteps run underbash -e.@conventional-commits/parser0.4.1.On CI, first run (commit 40b631f, run 37859252308, not counted): the pin worked. The action fetched the 15917651 zip and the emulator booted as
Android emulator version 37.1.11.0 (build_id 15917651). The first version of the guard ranemulator -version, which loads QEMU, and the runner has nolibpulse.so.0, so the step failed before the harness started on both API levels. My local check passed because it ran on a machine that has the library. The guard now readssource.propertiesinstead. That run also exercised the host evidence: itsharness-logsartifact heldhost.txt(a sample every 15 seconds) andhost-dmesg.txt.The proof is the runs of this workflow on this branch after that fix. This PR's own run counts if it ran the harness; further runs are
workflow_dispatchruns onclaude/pin-emulator, one at a time because the concurrency group cancels an in-progress run. Four clean API 34 runs in total, each showing:Android emulator version 37.1.11.0 (build_id 15917651)in the boot log, and the guard printingPkg.BuildId=15917651;hanging thread;native: 20/20 runs passedandnative: 6/6 runs passed;PASS release refuses the crash channeland the integration test passing.API 30 must stay green. A red caused only by the "received []" flake is hang-free but does not count toward the four. If the guard fails because another emulator was installed, the fallback is to install the build in
pre-emulator-launch-script(replace$ANDROID_HOME/emulatorfrom the same zip) and restart the count.Why four: if 37.1.11.0 were still hanging at the rate 37.2.12.0 did (10 of 10, a 95% lower bound of about 0.74), four clean runs by luck would have a chance of at most 0.5%.
Risk
EMULATOR_BUILD, which the comment says to do only after the harness passes on the new build.sdkmanagersystem-image install ever replaces the pinned emulator, the step fails on its first line instead of running on the wrong build. It checks the installed emulator, not the process; the boot log's first line names the build that actually ran.dl.google.comby the action. If Google withdrew it, the job would fail at install, not hang.EMULATOR_BUILD=16428233and the sampler would capture the evidence for that.🤖 Generated with Claude Code
https://claude.ai/code/session_01XLy7TiPAxtVjPKEwQ9iwBa