[Fix] (tools): cross-host runs first prove the WSL -> phone TCP path is end to end, and netbench's pkill no longer kills its own shell

This commit is contained in:
2026-09-28 22:57:20 -04:00
parent 221a8144c2
commit 429b4472bb
5 changed files with 49 additions and 64 deletions
+17 -8
View File
@@ -66,15 +66,24 @@ attach is SELinux-blocked for shell uid on the bench device, while same-uid
`/proc` reads via `run-as` work. Build for the device with the NDK
(`aarch64-linux-android*-clang`), push, run under `run-as`.
## tcp_path_check.sh — run before any cross-host measurement
Connects from WSL to a closed port on the phone. End to end, the phone refuses
it; if the connect is accepted, something on the host (here v2rayN's `xray_tun`,
WSL's default route) is terminating TCP and relaying it. That fakes sub-ms RTTs,
and on 2026-09-28 it stalled the MobileGL control stream. The stall read as a
server hang at eglMakeCurrent. Exit 0 = end to end, 1 = middlebox,
2 = filtered. Fix: `ip route replace <phone>/32 via <LAN gateway> dev eth0`
as root in WSL (temporary; delete it afterwards).
## netbench.sh — Wi-Fi TCP throughput baseline
WSL -> phone bulk transfer over `toybox nc` sink, 3 reps. The `nc` listener
must keep stdin open or it exits on EOF and RSTs the connection.
WSL -> phone bulk transfer over `toybox nc` sink, 3 reps; refuses to run
unless `tcp_path_check.sh` passes. The `nc` listener must keep stdin open or it
exits on EOF and RSTs the connection, and `pkill` must be anchored
(`'^toybox nc'`) or it kills the adb shell that is about to start the listener.
## phone_strace.sh / fdprobe.sh / wifi_hang_repro.sh — cross-host hang kit
## phone_strace.sh — session-child strace
Repro and evidence-capture for the cross-host control-plane hang (WSL client ->
phone server wedges at eglMakeCurrent; bytes ACKed, rx queue drained, session
child never sees POLLIN). `phone_strace.sh` attaches the device
`/system/bin/strace` as the app uid via `run-as` (shell-uid ptrace is blocked);
`fdprobe.sh` reconciles `/proc/<pid>/fd` socket inodes against `/proc/net/tcp`.
Attaches the device `/system/bin/strace` to the server's session child as the
app uid via `run-as` (shell-uid ptrace is blocked).
-33
View File
@@ -1,33 +0,0 @@
#!/bin/bash
# Repro hang, then map child fds -> socket inodes and dump per-socket rx queues + supervisor fds.
set -u
BASE=~/wifi-perf
export MOBILEGL_TRANSPORT=spawn
export MOBILEGL_IPC_CONTROL=tcp://192.168.21.181:40613
export MOBILEGL_IPC_DATA=stream
export MOBILEGL_IPC_TOKEN=wifibench-token-2026-09
export MOBILEGL_IPC_RUN_AHEAD=1
export MOBILEGL_IPC_COLD_START_MS=90000
export MOBILEGL_PIPE_STATS=1
cd ~/MobileGL
rm -rf "$BASE/out/fdprobe"; mkdir -p "$BASE/out/fdprobe"
./build-split/tools/trace_replay/mobilegl_trace_replay \
--trace "$BASE/traces/openra.trace" --backend DirectGLES \
--mobilegl-library ./build-split/libMobileGL.so --pbuffer-surface \
--benchmark --benchmark-result="$BASE/out/fdprobe/benchmark.json" \
--output "$BASE/out/fdprobe" > "$BASE/out/fdprobe/mobilegl.log" 2>&1 &
CPID=$!
echo "client pid=$CPID"
for i in $(seq 1 60); do
grep -q "MobileGL initialized" "$BASE/out/fdprobe/mobilegl.client.log" 2>/dev/null && break
sleep 1
done
sleep 8
echo "=== hang confirmed; dumping ==="
echo "=== CLIENT ss ==="
ss -tn dst 192.168.21.181:40613
echo "=== CLIENT bytes ==="
ss -ti dst 192.168.21.181:40613 | grep -E 'bytes_sent|ESTAB'
sleep 1
kill $CPID 2>/dev/null
echo DONE_LOCAL
+4 -2
View File
@@ -2,8 +2,10 @@
# Wi-Fi TCP throughput WSL -> phone, 3 reps, sink to /dev/null, nc restarted per rep.
set -u
PORT=5213
# Through a TCP-terminating proxy this measures the proxy, not Wi-Fi (the 09-28 run did).
bash "$(dirname "$0")/tcp_path_check.sh" || exit 1
for rep in 1 2 3; do
adb -s 2f7cbe2e shell "pkill -f 'toybox nc' 2>/dev/null; nohup toybox nc -4 -l -p $PORT -q 180 >/dev/null 2>/data/local/tmp/nc.err </dev/null & echo up_$rep"
adb -s 2f7cbe2e shell "pkill -f '^toybox nc' 2>/dev/null; nohup toybox nc -4 -l -p $PORT -q 180 >/dev/null 2>/data/local/tmp/nc.err </dev/null & echo up_$rep"
sleep 1
wsl -d Ubuntu -- bash -c "
python3 - <<'EOF'
@@ -25,7 +27,7 @@ except Exception as e:
print(f'rep: FAIL {e}')
EOF
"
adb -s 2f7cbe2e shell "pkill -f 'toybox nc' 2>/dev/null" >/dev/null
adb -s 2f7cbe2e shell "pkill -f '^toybox nc' 2>/dev/null" >/dev/null
sleep 1
done
echo NETBENCH_DONE
@@ -0,0 +1,28 @@
#!/bin/bash
# Is the WSL -> phone TCP path end to end? Run before any cross-host measurement.
#
# A TUN-mode proxy on the Windows host (v2rayN's xray_tun here, WSL's default route in mirrored
# mode) terminates every TCP connection itself and relays it: it ACKs locally (sub-ms "RTT",
# PMTU 9000), and on 2026-09-28 its relay stalled the MobileGL control stream at the same byte
# every run, which read as a server hang at eglMakeCurrent. Probe: connect to a port nothing
# listens on. End to end the phone answers RST (refused); a terminating middlebox accepts.
# Exit 0 = end to end, 1 = middlebox, 2 = cannot tell (filtered).
set -u
export MSYS_NO_PATHCONV=1
PHONE="${PHONE:-192.168.21.181}"
PROBE_PORT="${PROBE_PORT:-1}"
wsl.exe -d "${WSL_DISTRO:-Ubuntu}" -- bash -c "
ip -o route get $PHONE | head -1
python3 - <<'PY'
import socket, sys
s = socket.socket(); s.settimeout(3)
try:
s.connect(('$PHONE', $PROBE_PORT))
except ConnectionRefusedError:
print('OK: end to end (closed port $PROBE_PORT refused)'); sys.exit(0)
except socket.timeout:
print('UNKNOWN: no answer in 3 s (filtered)'); sys.exit(2)
print('FAIL: closed port $PROBE_PORT accepted - something between WSL and $PHONE terminates TCP '
'(TUN proxy?). Route around it as root, e.g. ip route replace $PHONE/32 via <LAN gateway> dev eth0')
sys.exit(1)
PY"
@@ -1,21 +0,0 @@
#!/bin/bash
# Start one openra client and leave it hanging on MakeCurrent for stack capture.
set -u
BASE=~/wifi-perf
export MOBILEGL_TRANSPORT=spawn
export MOBILEGL_IPC_CONTROL=tcp://192.168.21.181:40613
export MOBILEGL_IPC_DATA=stream
export MOBILEGL_IPC_TOKEN=wifibench-token-2026-09
export MOBILEGL_IPC_RUN_AHEAD=1
export MOBILEGL_IPC_COLD_START_MS=180000
export MOBILEGL_PIPE_STATS=1
cd ~/MobileGL
rm -rf "$BASE/out/hang"; mkdir -p "$BASE/out/hang"
./build-split/tools/trace_replay/mobilegl_trace_replay \
--trace "$BASE/traces/openra.trace" --backend DirectGLES \
--mobilegl-library ./build-split/libMobileGL.so --pbuffer-surface \
--benchmark --benchmark-result="$BASE/out/hang/benchmark.json" \
--output "$BASE/out/hang" > "$BASE/out/hang/mobilegl.log" 2>&1 &
echo "client pid=$!"
sleep 40
echo "SLEEP_DONE - client still running: $(jobs -p)"