Commit Graph
2440 Commits
Author SHA1 Message Date
SergioandClaude Opus 5 b221f06c01 arneses: los CINCO sandboxes de Gecko apagados, no un subconjunto a ojo
Cada arnés headless tenía su propio subconjunto de MOZ_DISABLE_*_SANDBOX, elegido en su
momento sin medir: banco 1 de 5, perfilar 4, codecs 3, ruteo 3, nativo 2, inicio 2. Con
cualquier subconjunto incompleto el sandbox de Firefox sigue intentando montar su
user-namespace dentro del de bwrap, falla con 'uid_map: EPERM' y deja un ayudante
'Sandbox Forked' muerto de SIGSEGV por cada intento — en el 100% de las corridas, después
de escribir el PNG y por eso invisible.

Medido: 2 cadáveres por corrida con sólo CONTENT apagado, 0 con los cinco. Verificado sobre
el arnés ya editado: segv=0 EPERM=0 screenshot=sí.

Acá no se pierde seguridad: bwrap ya es la jaula, el sandbox de Gecko es redundante y lo
único que hace dentro es fallar.

⚠ Cambia las condiciones de medición del banco de PGO: las cifras de docs/26 se tomaron con
el arnés viejo. Los cocientes del PGO comparan dos firefox bajo el mismo arnés y deberían
aguantar; la línea base absoluta de arranque no tiene por qué. Anotado en la cabecera.

No se tocan scripts/wlr/dunst-headless.sh (otro agente trabajando en él) ni los cazadores,
que conservan el entorno viejo a propósito para poder reproducir la condición original.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-08 16:11:28 +00:00
Sergio 846f2ec5a7 estado: cosecha granja 2026-09-08T16:02:43Z — avance del árbol KDE 2026-09-08 16:02:43 +00:00
SergioandClaude Opus 5 b405fc77df cuelgue headless RESUELTO: el sandbox de Firefox no puede montar su userns dentro de bwrap
No era la presión de memoria. La caza bajo presión (4 niveles × 20 corridas, con el nivel de
presión MEDIDO por MemAvailable y PSI) reprodujo el cuelgue por primera vez en 282 corridas
—2 de 80, 2,5%, compatible con el 3,5% original— pero SIN dosis-respuesta: los dos cuelgues
cayeron en el nivel con PSI 0,00 y los dos niveles apretados dieron cero.

Tres hipótesis muertas, cada una con su medición:
  · OOM se lleva al hijo   → oom_kill de /proc/vmstat no se movió (delta=0) y los hijos vivían
  · presión de memoria     → sin dosis-respuesta
  · fork server de Gecko   → A/B del pref: el proceso forkserver desaparece (35 muestras → 0,
                             o sea que el pref hizo efecto) y siguen los mismos 2 segfaults

La causa apareció comparando el log de una colgada con el de una BUENA, que es lo que faltaba:
en las 6 buenas TAMBIÉN revientan 2 hijos con SIGSEGV, después de escribir el PNG y por eso
invisibles. Muestreando /proc adentro, se llaman 'Sandbox Forked': los ayudantes que el sandbox
propio de Firefox forkea para montar su user-namespace, que no puede montar porque ya estamos
dentro del de bwrap ('writing /proc/self/uid_map: EPERM').

Las tres cantidades bajan juntas hasta cero, que es forma de cadena causal:

  sandbox completo            segv=7  SIN screenshot  EPERM=9  SandboxForked=725
  content.level=0             segv=2  con screenshot  EPERM=2  SandboxForked=68
  los 3 prefs .level a 0      segv=1  con screenshot  EPERM=1  SandboxForked=33
  las 5 MOZ_DISABLE_*         segv=0  con screenshot  EPERM=0  SandboxForked=0

Y el sandbox completo cuelga DETERMINISTA (rc=124 a los 180 s). Comparte familia con el
intermitente pero no está probado que sean el mismo: al determinista le faltan los 'Failed to
launch'. Queda dicho como lo que es.

Arreglo para cualquier firefox headless en bwrap (donde el sandbox de Gecko no aporta nada,
porque bwrap ya es la jaula):
  MOZ_DISABLE_{CONTENT,GMP,RDD,SOCKET_PROCESS,UTILITY}_SANDBOX=1

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-08 15:59:23 +00:00
Sergio cdadf5fa81 estado: cosecha granja 2026-09-08T15:33:28Z — avance del árbol KDE 2026-09-08 15:33:29 +00:00
Sergio 1ac819eff3 estado: cosecha granja 2026-09-08T15:01:44Z — avance del árbol KDE 2026-09-08 15:01:44 +00:00
SergioandClaude Opus 5 8ff6ae7b3a pgo: el control que faltaba — el arranque eran 16 s y diluía todos los porcentajes
El banco medía el ciclo COMPLETO del proceso (arrancar → renderizar → capturar → salir)
y nunca se midió cuánto de eso era arranque. Con una página vacía como control, y las 4
cargas × 2 variantes en UNA sola sesión intercalada (restar entre corridas de días
distintos no vale: la misma variante deriva ~1%):

  maquetación   trabajo 7281 → 4744 ms   -34,8%   (publicado: -10,9%)
  carga ajena   trabajo 4550 → 4634 ms    +1,8%   = cero, y es buena señal
  SunSpider     trabajo  -34 →   -6 ms   bajo el ruido

Dos correcciones al documento:

1. El -10,9% es correcto para el ciclo completo pero se leía como 'firefox 11% más
   rápido'. Sobre el trabajo de la página el PGO rinde -34,8%: tres veces más. El error
   subestimaba el propio resultado.

2. La explicación que di del SunSpider era aire. Su trabajo mide -34 ms, NEGATIVO: la
   página con el benchmark tardó menos que la vacía. No había nada que medir, y yo le
   colgué encima una teoría sobre el JIT. La teoría puede ser cierta; esta medición
   nunca la probó.

Las tablas viejas se dejan sin retocar, con un aviso arriba: el error de método enseña
más que el número corregido. Todo el rigor estadístico estaba puesto sobre una cantidad
que no era la que yo creía medir, y ninguna repetición lo habría revelado — sólo un
control, que costó siete corridas de una página vacía.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-08 14:57:26 +00:00
Sergio 9c491b29fc estado: cosecha granja 2026-09-08T14:31:50Z — avance del árbol KDE 2026-09-08 14:31:50 +00:00
Sergio 8c1378cb1f cazador: evidencia a favor de la hipótesis de presión de memoria
Al montar otro banco, la carga estaba en 3,34 (contra 0,13 de las cuatro cazas)
porque otro agente arrancó un cargo, y kswapd0 consumía CPU con CERO memoria
libre: recuperación de páginas bajo presión. Cada corrida mapea un libxul de
227 MB.

Es exactamente la condición que las cazas NO tenían y que los dos bancos con
cuelgues SÍ. No es prueba —el estado de aquellas ventanas no se reconstruye—
pero es la primera pista concreta, y cambia dónde buscar: cazar BAJO PRESIÓN de
memoria, no con la máquina ociosa.
2026-09-08 14:17:21 +00:00
Sergio 2e496d62e0 estado: tras aparcar el jarlog — corpus al día 2026-09-08 14:11:55 +00:00
Sergio c3413d293e jarlog APARCADO: rompe atuq, y el coste está medido mientras el beneficio no
Al reconstruir atuq sobre el firefox con jarlog, murió:

    zipfile.BadZipFile: Bad magic number for central directory  (rebrand.py)

El jarlog convierte el omni.ja al formato «jar optimizado» de Mozilla, que mueve
el directorio central al principio:

    sin jarlog:  PK\003\004    ZIP estándar — zipfile lo abre, 5306 entradas
    con jarlog:  \376\204#\0   zipfile lo rechaza

Y atuq reempaqueta el omni.ja con zipfile para su branding. O sea que el jarlog
rompe el navegador propio de la distro.

La cuenta es asimétrica: el COSTE está medido y el BENEFICIO no —el banco corre
con caché caliente, donde reordenar el omni.ja no ahorra ninguna lectura, y dio
-0,1%, por debajo del suelo de ruido del propio banco—. Cambiar algo que
funciona por una ganancia que no se pudo medir, rompiendo algo que sí
funcionaba, es mal negocio.

Revertido a los hashes YA construidos y medidos (perfil 3647c6be, firefox
3d199174, atuq fab2fbfb): cero reconstrucciones. La documentación va fuera de
los campos hasheados, verificado antes y después.

Se retoma cuando (1) se mida el arranque EN FRÍO, que es su terreno, y (2)
rebrand.py sepa leer el jar optimizado o des-optimizarlo antes. El blob
92497cdd del mirror ya trae el jarlog: retomarlo es cambiar una línea.

Y LA LECCIÓN, que es la que más vale: el jarlog parecía GRATIS. «Es lo que hace
upstream y no cuesta nada» lo escribí yo en este mismo documento hace unas
horas. El coste no apareció midiendo el jarlog sino CONSTRUYENDO LO QUE DEPENDÍA
DE ÉL. Una función que se declara gratuita sin haber reconstruido a sus
consumidores no es gratuita: es no medida.
2026-09-08 14:08:25 +00:00
Sergio 17508043aa estado: waterfox renombrado, corpus al día 2026-09-08 14:05:18 +00:00
Sergio 824ee67f0f estado: cosecha granja 2026-09-08T14:02:27Z — avance del árbol KDE 2026-09-08 14:02:27 +00:00
Sergio 54526f7d17 waterfox: instalado como waterfox y con lanzador — arranca y ya no colisiona
Dos defectos con un solo arreglo. El artefacto instalaba en usr/lib/firefox y
usr/bin/firefox —LAS MISMAS RUTAS que la receta firefox— y además tenía el mismo
fallo del lanzador que se le arregló a firefox ayer: verificado sobre el sellado,
CERO entradas de RUNPATH, así que moría con «Couldn't load XPCOM».

Se renombra el árbol a `waterfox` y se añade el lanzador con LD_LIBRARY_PATH.
Renombrar es seguro porque Firefox es REUBICABLE: localiza omni.ja relativo a su
propio binario, que es lo que hace que sus tarballs anden desde cualquier
directorio. NO se toca MOZ_APP_NAME: eso exigiría tocar confvars.sh del árbol y
arrastra el branding, que es la decisión que esta receta deja abierta y que no
se toma de paso.

Guardián nuevo: ni una ruta `firefox` en el artefacto. Si mach install cambia de
layout y algo vuelve a aterrizar ahí, la colisión regresa en silencio — dos
artefactos publicando el mismo fichero, y en la imagen gana uno sin que nada lo
diga.

Verificado CORRIENDO: arranca headless y renderiza (captura de 518.735 bytes,
idéntica en tamaño a la de firefox sobre la misma página).

Y correrlo destapó lo que ninguna inspección estática mostraba, anotado como
tercera cosa a decidir: WATERFOX SALE A LA RED AL ARRANCAR, SOLO, a bajar las
listas de su propio bloqueador desde easylist.to. Acá falla porque el sandbox no
tiene red; en una imagen real sería una conexión no solicitada en el primer
arranque. Esta distro apagó la telemetría de firefox exactamente por eso.
2026-09-08 14:02:24 +00:00
Sergio 64c9e7196e estado: cosecha granja 2026-09-08T13:32:16Z — avance del árbol KDE 2026-09-08 13:32:16 +00:00
Sergio 34af57ee3f estado: cosecha granja 2026-09-08T13:02:01Z — avance del árbol KDE 2026-09-08 13:02:01 +00:00
Sergio c1eb86c83b estado: cosecha granja 2026-09-08T12:31:51Z — avance del árbol KDE 2026-09-08 12:31:51 +00:00
Sergio f06a5627e0 estado: cosecha granja 2026-09-08T12:01:47Z — avance del árbol KDE 2026-09-08 12:01:47 +00:00
Sergio 5ac6f35030 estado: cosecha granja 2026-09-08T11:32:16Z — avance del árbol KDE 2026-09-08 11:32:16 +00:00
Sergio 11e2c5f3a2 cazador del cuelgue en headless: NO reproducido en 202 corridas, y qué descarta
Dos corridas del banco de PGO se colgaron en 120.034 y 120.030 ms — exactamente
el timeout del arnés, o sea bloqueos y no lentitud. Dos de 56 (~3,5%).

NO SE REPRODUJO. 202 corridas en cuatro condiciones, cero cuelgues:

  un binario, un sandbox compartido ......... 30 · 0
  4 binarios alternando, un sandbox ......... 60 · 0  (descarta churn de caché)
  4 binarios, UN SANDBOX NUEVO POR CORRIDA .. 56 · 0  (descarta los namespaces)
  ídem con LAS PÁGINAS EXACTAS del banco .... 56 · 0  (descarta la página)

Si la tasa fuera 3,5%, ver cero en 202 tendría probabilidad ~0,06%. La tasa real
bajo estas condiciones no es ésa, y lo que falta está fuera de ellas.

UN ERROR DE MÉTODO QUE COSTÓ 146 CORRIDAS, anotado en el script para no
repetirlo: las tres primeras cazas usaron flex.html y tablas.html porque las
tenía a mano, cuando las colgadas habían sido en fuera-del-corpus.html y
del-corpus.html. Estuve probando una condición que NO era la observada,
creyendo que sí. Antes de concluir «no se reproduce», comprobar que el
instrumento reproduce lo que dice reproducir.

Lo que sí se aprendió, y acota: es TODO O NADA. En 202 corridas ninguna pasó
siquiera de 45 s — o terminan en ~20 s o se bloquean hasta el timeout. No es
degradación, es bloqueo. Sobrevive la hipótesis que no se puede probar
retroactivamente: contención transitoria de otra cosa en la máquina —que es
compartida con otros agentes— durante esas dos ventanas.

El script queda para que la PRÓXIMA vez se capture en el acto (wchan, syscall,
state, memoria y carga del host, y el log del navegador de esa corrida) en vez
de empezar de cero.
2026-09-08 10:33:13 +00:00
Sergio 5d708f5225 estado: cosecha granja 2026-09-08T10:31:21Z — avance del árbol KDE 2026-09-08 10:31:21 +00:00
Sergio 59f8164b8b estado: cosecha granja 2026-09-08T10:02:10Z — avance del árbol KDE 2026-09-08 10:02:10 +00:00
Sergio 4aa3fbed66 estado: cosecha granja 2026-09-08T09:31:56Z — avance del árbol KDE 2026-09-08 09:31:56 +00:00
Sergio 01d4110241 estado: cosecha granja 2026-09-08T09:02:06Z — avance del árbol KDE 2026-09-08 09:02:06 +00:00
Sergio dce113cd3f estado: cosecha granja 2026-09-08T08:31:51Z — avance del árbol KDE 2026-09-08 08:31:51 +00:00
Sergio 613d74950b estado: cosecha granja 2026-09-08T08:01:43Z — avance del árbol KDE 2026-09-08 08:01:43 +00:00
Sergio 1ff5246667 estado: cosecha granja 2026-09-08T07:31:48Z — avance del árbol KDE 2026-09-08 07:31:49 +00:00
Sergio 57f9bf5b35 estado: cosecha granja 2026-09-08T07:01:44Z — avance del árbol KDE 2026-09-08 07:01:44 +00:00
Sergio 3306f8915d estado: cosecha granja 2026-09-08T06:31:24Z — avance del árbol KDE 2026-09-08 06:31:24 +00:00
Sergio e5b2d4e07d estado: cosecha granja 2026-09-08T06:01:46Z — avance del árbol KDE 2026-09-08 06:01:47 +00:00
Sergio d28a9313ab estado: cosecha granja 2026-09-08T05:31:26Z — avance del árbol KDE 2026-09-08 05:31:26 +00:00
Sergio c455a14611 estado: cosecha granja 2026-09-08T05:02:10Z — avance del árbol KDE 2026-09-08 05:02:10 +00:00
Sergio dd510d70e7 estado: cosecha granja 2026-09-08T04:31:59Z — avance del árbol KDE 2026-09-08 04:31:59 +00:00
Sergio 2584430a16 estado: cosecha granja 2026-09-08T04:01:28Z — avance del árbol KDE 2026-09-08 04:01:29 +00:00
Sergio 21bec8d02e estado: cosecha granja 2026-09-08T03:32:12Z — avance del árbol KDE 2026-09-08 03:32:12 +00:00
Sergio 92aacc6a5f SDD 26: el jarlog puesto — probado en el artefacto, no medible en el banco
sin PGO   v1        v2        v3 (= v2 + jarlog)
  DOM/maquetación   23.008    20.851    20.527    20.502   (-10,9%)
  SunSpider         16.006    15.859    15.869    15.838   (-1,0%)
  jarlog solo:      -0,1% y -0,2%

Indistinguible de cero, y el argumento no es que los rangos se solapen —que se
solapan— sino que la MISMA variante varía ~1% entre corridas de días distintos
(v1 dio 20.851 hoy y 21.050 ayer). El suelo de ruido del banco es diez veces el
efecto buscado.

No es un fallo del jarlog: el banco corre con la caché de página CALIENTE, y ahí
reordenar omni.ja no ahorra ninguna lectura. Su terreno es el arranque en frío,
que este instrumento no reproduce.

Lo que SÍ está probado es que la función existe, y del lado del artefacto:
libxul IDÉNTICO byte a byte entre v2 y v3, omni.ja distinto en 26 bytes. El
jarlog tocó exactamente lo que debía y nada más. Se conserva porque es lo que
hace upstream y no cuesta nada; lo que no se afirma es una ganancia no medida.

Y no hizo falta la extensión Quitter, que este mismo documento daba por
bloqueante: profileserver.py sólo traduce JARLOG_FILE a MOZ_JAR_LOG_FILE.

Anotado además: los dos atípicos del banco son 120.034 y 120.030 ms, o sea
exactamente el timeout del arnés. No son ruido de carga sino corridas COLGADAS
al arrancar en headless, 2 de 56 (~3,5%).
2026-09-08 03:31:23 +00:00
Sergio 89b296cac9 estado: cosecha granja 2026-09-08T03:01:49Z — avance del árbol KDE 2026-09-08 03:01:49 +00:00
Sergio 91a229a7c4 estado: cosecha granja 2026-09-08T02:32:04Z — avance del árbol KDE 2026-09-08 02:32:04 +00:00
Sergio d9833a581b jarlog: la mitad del PGO que faltaba — el orden de omni.ja para el arranque
El jarlog registra en qué orden se LEEN los ficheros dentro de omni.ja al
arrancar; con él, el empaquetador los reordena y el arranque hace lecturas
secuenciales en vez de saltar por el archivo.

NO hizo falta la extensión Quitter de Mozilla, que era lo que yo daba por
bloqueante: basta MOZ_JAR_LOG_FILE en el entorno del navegador. Su
profileserver.py sólo traduce JARLOG_FILE a esa variable — leerlo costó un grep
y ahorró rehacer el arnés entero.

Y se genera en una corrida APARTE, que está medido y no supuesto. Mozilla lo
emite en la misma sesión del profileserver; nuestro arnés arranca un navegador
POR PÁGINA, así que había que saber si el fichero se acumula o se pisa. Se pisa:
tras rejilla.html y tras tablas.html dio exactamente los mismos 27.652 bytes y
469 líneas. Su contenido lo domina el ARRANQUE, no la página, así que una
corrida dedicada vale igual que una de 46 — rehacer el perfilado sólo para
obtenerlo habría sido gasto sin diferencia. Se conserva el profdata ya medido
(el del -11,4%), que es lo que hace comparables los números.

Guardián propio: un jarlog vacío o que no nombre los archivos reales NO rompe el
build de firefox, sólo deja el omni.ja sin ordenar — o sea que se pierde justo
lo que se vino a buscar, en silencio. Se exige que mencione los DOS archivos que
el navegador abre (omni.ja y browser/omni.ja).
2026-09-08 02:16:53 +00:00
Sergio b00d513fbb estado: cosecha granja 2026-09-08T02:01:48Z — avance del árbol KDE 2026-09-08 02:01:48 +00:00
Sergio 0d03050b2b estado: cosecha granja 2026-09-08T01:32:00Z — avance del árbol KDE 2026-09-08 01:32:00 +00:00
Sergio b5582a2bd9 estado: cosecha granja 2026-09-08T01:02:14Z — avance del árbol KDE 2026-09-08 01:02:14 +00:00
Sergio 84ff534d43 estado: cosecha granja 2026-09-08T00:01:54Z — avance del árbol KDE 2026-09-08 00:01:54 +00:00
Sergio d971413a89 estado: cosecha granja 2026-09-07T23:31:52Z — avance del árbol KDE 2026-09-07 23:31:52 +00:00
Sergio 0a1d087eaa estado: cosecha granja 2026-09-07T23:01:53Z — avance del árbol KDE 2026-09-07 23:01:53 +00:00
Sergio 67269a028a estado: cosecha granja 2026-09-07T22:32:00Z — avance del árbol KDE 2026-09-07 22:32:00 +00:00
Sergio 1dbaf8d85a estado: atuq sobre el firefox con PGO v2 — 860/862 y cero huecos
atuq b3:fab2fbfb, 340 M, libxul de 227.043.776 bytes: el mismo del motor con el
perfil de 46 páginas. Verificado que ARRANCA desde una hidratación limpia de
escritorio-sway, 0 errores de relocación.

El corpus queda en 860/862 sellados —los dos que faltan son `ajeno`, que es
frontera y no deuda— y el vigía de sonames en CERO huecos en los cinco perfiles.
2026-09-07 22:08:38 +00:00
Sergio 54a27b966b estado: cosecha granja 2026-09-07T22:02:23Z — avance del árbol KDE 2026-09-07 22:02:23 +00:00
Sergio 6b469a81d2 SDD 26: el corpus ampliado rinde — de -9,6% a -11,4% en maquetación
sin PGO    v1 (36 pág)      v2 (46 pág)
  DOM/maquetación       23.285 ms  21.050 (-9,6%)   20.640 (-11,4%)
  SunSpider 3d-raytrace 16.003 ms  15.846 (-1,0%)   15.857 (-0,9%)

La mejora en maquetación NO se afirma por las medianas sino por la separación:
SEIS de las siete muestras de v1 son más lentas que TODAS las de v2; sólo una
cae dentro del rango de v2.

En SunSpider v1 y v2 son INDISTINGUIBLES —los valores se entrelazan por
completo—, que es exactamente lo esperable: ese camino lo ejecuta el JIT y el
PGO no lo toca. Un corpus mejor no puede mejorar lo que el PGO no alcanza. El
-0,9% frente al -1,0% no dice que v2 sea peor ahí: dice que no se distingue.

Una de las siete corridas de v2 dio 120.029 ms contra ~20.600 de las otras seis.
La mediana lo ignora por diseño; una media lo habría convertido en «v2 es
catastróficamente peor». Fue la razón de elegir mediana antes de ver un número.

Y lo que el banco no puede afirmar, escrito: las 10 páginas nuevas ejercitan los
mismos subsistemas que la página de medición, así que el parentesco con lo que
ahora se entrena es mayor que antes. El -11,4% es real para ESTA carga;
generalizarlo a «cualquier página» sería el mismo error que cometía el corpus de
Mozilla, en la otra dirección.
2026-09-07 21:52:39 +00:00
Sergio 9769614866 estado: cosecha granja 2026-09-07T21:32:10Z — avance del árbol KDE 2026-09-07 21:32:10 +00:00
SergioandClaude Opus 5 b8865560c0 SDD 26 §8: la unidad 4.e deja de ser una afirmación y pasa a estar medida
`scripts/test-atuq-inicio.py` le pregunta al motor por sus overrides en vez de
mirar el XPI en el disco: moz-extension://…/inicio.html en las dos, contra
about:home / about:newtab cuando se le saca el XPI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NNFzrqFBEt6W7maGJKf2Xs
2026-09-07 21:03:35 +00:00