#!/bin/bash # verificar-arreglo-sandbox.sh — A/B del arreglo del cuelgue: arnés VIEJO contra arnés ARREGLADO, # intercalados, bajo la presión de memoria en la que aparecieron los cuelgues. # # VIEJO = MOZ_DISABLE_CONTENT_SANDBOX=1 solamente ⇒ 2 segfaults de 'Sandbox Forked' por corrida # ARREGLADO = las 5 MOZ_DISABLE_*_SANDBOX ⇒ 0 segfaults, 0 EPERM, 0 helpers # # El marcador que se mide NO es el cuelgue (2,5 %: haría falta muchísima corrida) sino el SEGFAULT, # que está en el 100 % de las corridas del arnés viejo. Un mecanismo presente siempre se puede # refutar con pocas muestras; un síntoma raro, no. El recuento de cuelgues va igual, como control. set -u RAIZ=/mnt/vvv/takana; R=$RAIZ/store/.rootfs/sway-v2 AQUI=$(cd "$(dirname "$0")" && pwd); N=${N:-50}; UMBRAL=${UMBRAL:-60} A=$(ls -d $RAIZ/store/3d199174*-firefox | head -1) VIEJO='MOZ_DISABLE_CONTENT_SANDBOX=1' NUEVO='MOZ_DISABLE_CONTENT_SANDBOX=1 MOZ_DISABLE_GMP_SANDBOX=1 MOZ_DISABLE_RDD_SANDBOX=1 MOZ_DISABLE_SOCKET_PROCESS_SANDBOX=1 MOZ_DISABLE_UTILITY_SANDBOX=1' declare -A SEGV COLG SHOT for k in viejo nuevo; do SEGV[$k]=0; COLG[$k]=0; SHOT[$k]=0; done python3 "$AQUI/presion-memoria.py" 2000 3600 >/dev/null 2>&1 & HOG=$! trap 'kill $HOG 2>/dev/null' EXIT for _ in $(seq 1 40); do sleep 2; [ "$(awk '/MemAvailable/{print int($2/1024)}' /proc/meminfo)" -le 2300 ] && break; done echo "presión lista: disponible=$(awk '/MemAvailable/{print int($2/1024)}' /proc/meminfo) MiB" for i in $(seq 1 $N); do for k in viejo nuevo; do [ $k = viejo ] && ENV="$VIEJO" || ENV="$NUEVO" SAL=$(mktemp -d) # ⚠ `setsid` + matar el GRUPO, no el bwrap (medido 2026-09-08, DOS veces el mismo día). # `kill $BW` mata el bwrap EXTERIOR, que no es el init del namespace de PID: el firefox de # dentro sobrevive. Y si el arnés corría bajo `flock`, ese superviviente HEREDA el fd del lock # y deja a la granja sin poder compilar hasta que alguien lo note — pasó hora y media, en # silencio. Medido: matando sólo el bwrap queda 1 firefox vivo; matando el grupo, 0. setsid bwrap --ro-bind "$R" / --ro-bind /usr/lib/musl/lib/libc.so /lib/ld-musl-x86_64.so.1 \ --ro-bind "$A/usr/lib/firefox" /usr/lib/firefox --dev /dev --proc /proc --tmpfs /run --tmpfs /tmp \ --unshare-pid --ro-bind "$AQUI" /bench --bind "$SAL" /salida --unshare-user --uid 0 --gid 0 \ --setenv PATH /usr/bin:/bin --setenv APAGA "$ENV" \ /bin/sh -c 'export HOME=/tmp/h MOZ_HEADLESS=1 LIBGL_ALWAYS_SOFTWARE=1 LANG=C.UTF-8; mkdir -p $HOME; export $APAGA LD_LIBRARY_PATH=/usr/lib/firefox /usr/lib/firefox/firefox --headless --screenshot /salida/x.png file:///bench/fuera-del-corpus.html' \ >"$SAL/nav.log" 2>&1 & BW=$!; t=0 while kill -0 $BW 2>/dev/null && [ $t -lt $UMBRAL ]; do sleep 1; t=$((t+1)); done if kill -0 $BW 2>/dev/null; then COLG[$k]=$(( ${COLG[$k]} + 1 )); cp -r "$SAL" "$RAIZ/work/colgada-$k-$i" 2>/dev/null kill -TERM -$BW 2>/dev/null; sleep 3; kill -KILL -$BW 2>/dev/null # el GRUPO else wait $BW 2>/dev/null SEGV[$k]=$(( ${SEGV[$k]} + $(grep -c 'exited on signal 11' "$SAL/nav.log") )) [ -f "$SAL/x.png" ] && SHOT[$k]=$(( ${SHOT[$k]} + 1 )) fi rm -rf "$SAL" done [ $((i % 10)) = 0 ] && echo " $i/$N · viejo segv=${SEGV[viejo]} colg=${COLG[viejo]} · nuevo segv=${SEGV[nuevo]} colg=${COLG[nuevo]}" done echo "" for k in viejo nuevo; do printf "%-10s segfaults=%-4s COLGADAS=%-3s screenshots=%s/%s\n" "$k" "${SEGV[$k]}" "${COLG[$k]}" "${SHOT[$k]}" "$N" done