Match an AVD name as a whole argument, never as a prefix

`emu up` kills a stray process for its own AVD first, with `pkill -f
"[e]mulator.*-avd $avd"`. An AVD name is a prefix of every longer one, so
`-avd ai-app` matched `-avd ai-app-2`: starting one checkout's emulator
silently killed another checkout's. That is the exact interference this tool
exists to prevent, and from the other side it looked like an emulator dying
on its own -- twice on 2026-08-31 before the pattern was the suspect, with
nothing in its log but a graceful shutdown nobody had asked for.

`emu list` had the same hazard in its `index($0, want)`, where the cost is
quieter: with both up it reported ai-app-2's resident size against ai-app,
which is a number that looks entirely plausible.

`running_avds` and `avd_serial` were already exact matches, which is what
made this hard to see -- the rule was right in two places out of four.

Verified with both emulators running: the ai-app pattern now matches only
ai-app, and `emu list` reports the two sizes separately.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Opus 5 committed 2026-08-31 00:17:13 -04:00
1 parent 1d71730b56
commit 098433681e
1 file changed
+14 -2
+14 -2
View File
@@ -66,8 +66,12 @@ cmd_list() {
# line, so this cannot match the shell running it: that shell's # line, so this cannot match the shell running it: that shell's
# command line contains this pattern, and a `ps | awk` that matches # command line contains this pattern, and a `ps | awk` that matches
# itself reports the size of the shell. # itself reports the size of the shell.
# Whole argument rather than a prefix, for the reason `cmd_up`
# gives: with both up, a substring match reported ai-app-2's size
# against ai-app, which is a number that looks entirely plausible.
rss=$(ps -eo rss=,comm=,args= | rss=$(ps -eo rss=,comm=,args= |
awk -v want="-avd $name" '$2 ~ /^qemu-system/ && index($0, want) {print int($1/1024); exit}') awk -v want="-avd $name" '$2 ~ /^qemu-system/ &&
match($0, want "([[:space:]]|$)") {print int($1/1024); exit}')
printf ' %-16s %-24s %s\n' "$serial" "$name" "${rss:+$rss MB}" printf ' %-16s %-24s %s\n' "$serial" "$name" "${rss:+$rss MB}"
done < <(running_avds "$adb") done < <(running_avds "$adb")
[ "$found" = true ] || echo " (none attached)" [ "$found" = true ] || echo " (none attached)"
@@ -206,7 +210,15 @@ cmd_up() {
# A stray process for this AVD that never registered with adb. The # A stray process for this AVD that never registered with adb. The
# bracketed first character keeps the pattern from matching the shell # bracketed first character keeps the pattern from matching the shell
# running this script, which would kill it mid-flight. # running this script, which would kill it mid-flight.
pkill -f "[e]mulator.*-avd $avd" >/dev/null 2>&1 || true #
# The trailing boundary is the other half, and it is not decoration: an
# AVD name is a *prefix* of every longer one, so `-avd ai-app` matched
# `-avd ai-app-2` and starting one checkout's emulator silently killed
# another checkout's. That is the exact interference this whole tool
# exists to prevent, and it looked from the other side like an emulator
# dying on its own -- twice, on 2026-08-31, before the pattern was the
# suspect. Match the name as a whole argument, never as a prefix.
pkill -f "[e]mulator.*-avd $avd([[:space:]]|\$)" >/dev/null 2>&1 || true
log="/tmp/$avd-emulator.log" log="/tmp/$avd-emulator.log"
rm -f "$log" rm -f "$log"