The run of work that took the translated build from "boots" to "playable". Engine: - Flat guest mapping replaces the software MMU on aarch64 hosts. A 4 GiB PROT_NONE reservation lets a 32-bit guest address zero-extend safely, so tcg_out_qemu_ld/st short-circuit before tcg_out_tlb_read and the prologue materialises the base into X28. Measured 1.24x (51 vs 41 fps, interleaved A/B). Note the base must be set BEFORE UC_INIT - Unicorn inits lazily, and setting it after uc_open silently falls back to softmmu. - num_get<char> facet implemented, which was the real cause of the crash after the prologue race; a full race is now playable end to end. - Thread-stack free list + ReleaseThreadEngine, fixing the arena leak that showed up as a black screen when entering a race. kMaxGuestThreads 16 -> 64. - Real ARM32 FMOD now runs in-engine via the Java FMODAudioDevice bridge, with a per-thread JNIEnv. Two of the three blockers were our own single-image-era guards. Host/app: - Native crash handler: async-signal-safe, decodes the host fault back to a guest address, writes a report file and nothing else. CrashReportActivity picks it up on the NEXT launch, zips it, and offers to share. No backend, no automatic upload. - Game data ships inside the APK and self-extracts on first launch, so a tester installs one file and plays. Copy-to-.part-then-rename, with a free-space check up front. - EGL context preserved across pause, fixing black textures on resume. - Navigation bar hidden and re-hidden on focus gain; volume keys reported as system keys, checked before the loading-state gate. - x86_64 added to abiFilters: the ARM32 guest runs under tcg/i386 with no houdini in the path. The flat mapping is aarch64-only, so that host falls back to the software MMU - commented at the abiFilters line. Ignore rules added for app/translated/ (611 MB of signed release APK, which also carries the bundled OBB) and ostream_repro/build/. Co-Authored-By: Claude <noreply@anthropic.com>
104 lines
4.0 KiB
Bash
Executable File
104 lines
4.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Repeatable on-device smoke test for the ARM32-in-ARM64 prototype (see
|
|
# /ARM64_TRANSLATION_LAYER.md). Replaces the manual adb-shell archaeology
|
|
# this project's live debugging sessions have needed up to now: install,
|
|
# launch, watch logcat for a bounded window, then report the same signals
|
|
# those sessions kept hand-checking - onCreate timing, MEM FAULT count (see
|
|
# guest_engine.cpp's mem_fault_hook_cb), and process-death cause (ANR / OOM /
|
|
# MIUI SwipeUpClean / other) - as one command, so every future interface-
|
|
# layer change gets checked against the same baseline instead of a fresh
|
|
# investigation each time.
|
|
#
|
|
# Usage: mpcore/scripts/test_on_device.sh [device-serial] [watch-seconds]
|
|
# device-serial defaults to the first device `adb devices` lists.
|
|
# watch-seconds defaults to 180 (most observed onCreate runs finish in
|
|
# 100-120s; this leaves headroom to also see the post-onCreate lifecycle
|
|
# calls that previously kept faulting).
|
|
set -uo pipefail
|
|
# Script lives at mpcore/scripts/ - project root (where app/ and mpcore/ are
|
|
# siblings) is two levels up.
|
|
cd "$(dirname "$0")/../.."
|
|
|
|
PKG="com.ea.games.nfs13_arm"
|
|
ACTIVITY="com.ea.ironmonkey.GameActivityMain"
|
|
# "translated" (the emulated arm64-v8a path) - see app/build.gradle.kts's
|
|
# product flavors, added for the native ARM32 tracing investigation
|
|
# (ARM64_TRANSLATION_LAYER.md). The pre-flavor-split path
|
|
# (app/build/outputs/apk/debug/app-debug.apk) is now a STALE, never-updated
|
|
# file left over from before that split - silently reinstalling it here
|
|
# instead of the real current build wasted real debugging time confirming
|
|
# this fix, so this path is now the single source of truth.
|
|
APK="app/build/outputs/apk/translated/debug/app-translated-debug.apk"
|
|
|
|
SERIAL="${1:-$(adb devices | awk 'NR==2{print $1}')}"
|
|
WATCH_SECONDS="${2:-180}"
|
|
|
|
if [[ -z "$SERIAL" ]]; then
|
|
echo "No adb device found. Connect the device and retry." >&2
|
|
exit 1
|
|
fi
|
|
ADB="adb -s $SERIAL"
|
|
|
|
if [[ ! -f "$APK" ]]; then
|
|
echo "APK not found at $APK - build it first (./gradlew :app:assembleDebug)." >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "== Installing $APK on $SERIAL =="
|
|
$ADB install -r "$APK" || { echo "install failed" >&2; exit 1; }
|
|
|
|
echo "== Launching =="
|
|
$ADB shell am force-stop "$PKG"
|
|
$ADB logcat -c
|
|
$ADB shell monkey -p "$PKG" -c android.intent.category.LAUNCHER 1 >/dev/null
|
|
|
|
sleep 2
|
|
PID=$($ADB shell pidof "$PKG" | tr -d '\r')
|
|
if [[ -z "$PID" ]]; then
|
|
echo "Process did not start." >&2
|
|
exit 1
|
|
fi
|
|
echo "pid=$PID"
|
|
|
|
echo "== Watching logcat for ${WATCH_SECONDS}s =="
|
|
LOG="$(mktemp)"
|
|
timeout "${WATCH_SECONDS}s" $ADB logcat --pid="$PID" > "$LOG" 2>/dev/null || true
|
|
|
|
echo ""
|
|
echo "===================== RESULTS ====================="
|
|
|
|
ONCREATE_LINE=$(grep "GameActivityMain onCreate took" "$LOG" | tail -1)
|
|
if [[ -n "$ONCREATE_LINE" ]]; then
|
|
echo "onCreate: $(echo "$ONCREATE_LINE" | grep -oE '[0-9]+ms')"
|
|
else
|
|
echo "onCreate: did not complete within ${WATCH_SECONDS}s"
|
|
fi
|
|
|
|
FAULT_COUNT=$(grep -c "MEM FAULT" "$LOG" || true)
|
|
echo "MEM FAULT lines: $FAULT_COUNT"
|
|
if [[ "$FAULT_COUNT" -gt 0 ]]; then
|
|
echo " first: $(grep "MEM FAULT" "$LOG" | head -1)"
|
|
echo " last: $(grep "MEM FAULT" "$LOG" | tail -1)"
|
|
fi
|
|
|
|
CRASHED_LINE=$(grep -c "refusing to run - engine already crashed" "$LOG" || true)
|
|
echo "engine crashed (fail-fast tripped): $([[ "$CRASHED_LINE" -gt 0 ]] && echo yes || echo no)"
|
|
|
|
STILL_ALIVE=$($ADB shell "pidof $PKG" | tr -d '\r')
|
|
if [[ -n "$STILL_ALIVE" ]]; then
|
|
echo "process status: alive (pid=$STILL_ALIVE) at end of watch window"
|
|
else
|
|
echo "process status: DEAD"
|
|
DEATH_LINE=$($ADB logcat -d 2>/dev/null | grep -E "Killing $PID:|$PID.*died->background" | tail -3)
|
|
if [[ -n "$DEATH_LINE" ]]; then
|
|
echo " cause:"
|
|
echo "$DEATH_LINE" | sed 's/^/ /'
|
|
else
|
|
echo " cause: unknown (no ActivityManager kill/death line found - check for a FATAL crash instead)"
|
|
$ADB logcat -d --pid="$PID" 2>/dev/null | grep -iE "FATAL|AndroidRuntime" | sed 's/^/ /'
|
|
fi
|
|
fi
|
|
|
|
echo "====================================================="
|
|
echo "Full log: $LOG"
|