gnome: cae el SIGSEGV — el shell toma DRM master e input; muro nuevo en la hebra de input
Dos bugs REALES de arje-logind-compat, encontrados arrancando la imagen y
arreglados (con test) en el árbol de tawasuyu — todavía LOCALES, sin pushear:
1. La sesión se creaba PEREZOSAMENTE. `ensure_user` sólo corría dentro de un
método del Manager, y `write_login_state` vive adentro. Pero mutter no
empieza por D-Bus: lo primero que hace es sd_pid_get_session(), que
arje-sdlogin-compat resuelve LEYENDO /run/systemd/sessions. Huevo y gallina:
el estado en disco sólo se escribía después de un pedido que sólo ocurre si
el estado ya existe. Ahora se crea al arrancar (eager_session).
2. El object path de la Session estaba MAL ESCAPADO: era `/session/_1`. La
convención de systemd (bus_label_escape) codifica `_<hex>` todo lo que no sea
[A-Za-z0-9] **y también el primer carácter si es dígito** ⇒ el id "1" da
`_31`. Importa porque el cliente calcula el path por su cuenta y NO pregunta:
mutter reimplementa la misma regla en meta-dbus-utils.c. Con `_1` no había
nadie sirviendo ahí, la propiedad `Seat` volvía NULL y mutter —que no
chequea— moría de SIGSEGV en get_seat_proxy. Los objetos User NO usan este
escapado (systemd hardcodea `_<uid>`), así que user_path() queda igual.
Y ARJE_LOGIN_STATE=1 YA EXISTÍA: el comentario del daemon dice literalmente "en
arje (sin systemd) el launcher de sesión lo prende. Default off" — y el launcher
es gnome-start. El puente que escribía /run/systemd/ a mano era reinventar esa
perilla; queda de fallback inerte.
Resultado: el shell ya no crashea. Corre con 12 hilos, /dev/dri/card0 abierto
tres veces y /dev/input/event0 abierto — el TakeDevice de logind funciona y el
compositor tiene DRM master e input. Queda bloqueado en
meta_seat_impl_initable_init (meta-seat-impl.c:3154): espera en un condvar a que
la "Mutter Input Thread" avise que inicializó, y nunca avisa. Hipótesis principal
libudev-zero, que ya dio un episodio idéntico en el frente de la USB nvidia.
El gnome-start ahora le fuerza un core con SIGABRT al proceso colgado: sin gdb en
la imagen es la única forma de ver dónde está parado.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -48,6 +48,16 @@ export LP_NUM_THREADS=1
|
||||
# en virtio-gpu con render software ⇒ cursor invisible) y modeset simple en vez de atomic.
|
||||
export MUTTER_DEBUG_DISABLE_HW_CURSORS=1
|
||||
export MUTTER_DEBUG_FORCE_KMS_MODE=simple
|
||||
# MUTTER_DEBUG_KMS_THREAD_TYPE=user: mutter corre su hebra KMS con prioridad de TIEMPO REAL por
|
||||
# defecto. En esta VM no hay privilegios de RT scheduling, y el síntoma es exactamente el que dio el
|
||||
# diagnóstico — hilo principal dormido en `futex_do_wait` con la "KMS thread" viva pero sin avanzar,
|
||||
# el shell con /dev/dri/card0 ya abierto y ningún socket wayland creado nunca.
|
||||
export MUTTER_DEBUG_KMS_THREAD_TYPE=user
|
||||
# MUTTER_DEBUG_SEND_KMS_MODIFIERS=0: el equivalente en mutter del KWIN_DRM_USE_MODIFIERS=0 que costó
|
||||
# la campaña KDE. virtio-gpu ANUNCIA soportar drmModeAddFB2WithModifiers pero RECHAZA el modifier
|
||||
# explícito (aun LINEAR=0) con EINVAL ⇒ no se puede crear el framebuffer del compositor. Los nombres
|
||||
# de estas variables están verificados contra los strings de libmutter-16.so.0, no de memoria.
|
||||
export MUTTER_DEBUG_SEND_KMS_MODIFIERS=0
|
||||
|
||||
if [ "${DIAG:-1}" = 1 ]; then
|
||||
export G_MESSAGES_DEBUG=all
|
||||
@@ -96,6 +106,11 @@ say "dbus sesión: ${DBUS_SESSION_BUS_ADDRESS:-NO ARRANCO}"
|
||||
# SU sesión vía la C-ABI sd-login, que libelogind resuelve LEYENDO /run/systemd/sessions. Sin este
|
||||
# daemon esos ficheros no existen y mutter muere en "Failed to find any matching session".
|
||||
if [ -x /usr/bin/arje-logind-compat ]; then
|
||||
# ARJE_LOGIN_STATE=1: la perilla que YA traía el daemon y que nadie prendía. Su comentario en
|
||||
# arje-compat lo dice explícito — "en un host CON systemd real pisaría su estado; en arje (sin
|
||||
# systemd) el launcher de sesión lo prende. Default off" — y el launcher de sesión es ESTE script.
|
||||
# Con ella escribe /run/systemd/{sessions,seats,users}, que es lo que libelogind lee.
|
||||
export ARJE_LOGIN_STATE=1
|
||||
/usr/bin/arje-logind-compat >/tmp/logind-compat.log 2>&1 &
|
||||
i=0
|
||||
while [ $i -lt 40 ]; do
|
||||
@@ -175,7 +190,7 @@ SHELL_PID=$!
|
||||
# la entrada zombi. Se mira el State de /proc en su lugar.
|
||||
alive() { s=$(sed -n 's/^State:[[:space:]]*//p' /proc/$1/status 2>/dev/null); case "$s" in ""|Z*) return 1;; *) return 0;; esac; }
|
||||
i=0
|
||||
while [ $i -lt 90 ]; do
|
||||
while [ $i -lt 240 ]; do
|
||||
[ -S "$XDG_RUNTIME_DIR/wayland-0" ] && break
|
||||
alive $SHELL_PID || { wait $SHELL_PID; RC=$?; say "!! gnome-shell murió (código $RC) antes de exponer wayland-0:"; dump /tmp/gnome-shell.log; say "cores: $(ls /core.* 2>/dev/null | tr '\n' ' ' || echo NINGUNO)"; exec /bin/sh; }
|
||||
i=$((i+1)); sleep 0.5
|
||||
@@ -183,17 +198,25 @@ done
|
||||
if [ -S "$XDG_RUNTIME_DIR/wayland-0" ]; then
|
||||
say "compositor OK (wayland-0) — el shell ES el display server"
|
||||
else
|
||||
say "!! sin wayland-0 tras 45s:"; dump /tmp/gnome-shell.log
|
||||
say "!! sin wayland-0 tras 120s:"; dump /tmp/gnome-shell.log
|
||||
# El shell NO murió: quedó COLGADO. Sin gdb en la imagen, el diagnóstico barato es dónde está
|
||||
# bloqueado el hilo principal (wchan) y contra qué socket, que es lo que distingue "esperando una
|
||||
# respuesta D-Bus que no llega" de "spinning en el renderer".
|
||||
say "--- diagnóstico del cuelgue (pid $SHELL_PID) ---"
|
||||
say "XDG_RUNTIME_DIR ($XDG_RUNTIME_DIR): $(ls -a $XDG_RUNTIME_DIR 2>/dev/null | tr '\n' ' ')"
|
||||
say "sockets wayland en el sistema: $(find / -name 'wayland-*' -maxdepth 6 2>/dev/null | tr '\n' ' ')"
|
||||
say "wchan: $(cat /proc/$SHELL_PID/wchan 2>/dev/null)"
|
||||
say "state: $(grep -a ^State /proc/$SHELL_PID/status 2>/dev/null)"
|
||||
say "stack principal:"; cat /proc/$SHELL_PID/stack > /dev/ttyS0 2>/dev/null
|
||||
say "syscall: $(cat /proc/$SHELL_PID/syscall 2>/dev/null)"
|
||||
say "fds abiertos:"; ls -l /proc/$SHELL_PID/fd 2>/dev/null > /dev/ttyS0
|
||||
say "hilos: $(ls /proc/$SHELL_PID/task 2>/dev/null | wc -l)"
|
||||
# Sin gdb en la imagen, la única forma de ver DÓNDE está bloqueado es forzarle un core y leerlo
|
||||
# con el gdb del host (`thread apply all bt`). SIGABRT lo produce y no lo maneja nadie.
|
||||
say "forzando core del proceso colgado (SIGABRT)..."
|
||||
kill -ABRT $SHELL_PID 2>/dev/null
|
||||
sleep 12; sync; sync
|
||||
say "cores: $(ls -la /core.* 2>/dev/null | tr '\n' ' ' || echo NINGUNO)"
|
||||
for t in $(ls /proc/$SHELL_PID/task 2>/dev/null); do
|
||||
say " tid $t wchan=$(cat /proc/$SHELL_PID/task/$t/wchan 2>/dev/null) comm=$(cat /proc/$SHELL_PID/task/$t/comm 2>/dev/null)"
|
||||
done
|
||||
|
||||
@@ -88,8 +88,14 @@ echo "==> inyectando arje-logind-compat (el login1 del fractal)"
|
||||
# LEYENDO /run/systemd/{sessions,users,seats}. Pero alguien tiene que ESCRIBIR esos ficheros, y ese
|
||||
# alguien es arje-logind-compat, el daemon D-Bus que se hace pasar por org.freedesktop.login1.
|
||||
# libelogind entra solo (es dep de mutter); el daemon no, porque nadie lo declara como dep de build.
|
||||
ALC="${ALC:-$(ls -dt store/*-arje-logind-compat 2>/dev/null | head -1)}"
|
||||
if [ -n "$ALC" ] && [ -d "$ALC" ]; then
|
||||
# ALC_BIN permite inyectar un binario RECIÉN COMPILADO en vez del artefacto sellado. Es para probar
|
||||
# un cambio en arje-compat antes de commitear/pushear tawasuyu y re-sellar la receta (la receta pina
|
||||
# un commit, así que sin push no hay artefacto nuevo). Lo que se pruebe así NO es reproducible: es
|
||||
# andamio de iteración, y el camino de producción sigue siendo el artefacto del store.
|
||||
if [ -n "${ALC_BIN:-}" ] && [ -x "$ALC_BIN" ]; then
|
||||
install -Dm755 "$ALC_BIN" "$MERGED"/usr/bin/arje-logind-compat
|
||||
echo " ⚠ binario LOCAL (no sellado): $ALC_BIN"
|
||||
elif ALC="${ALC:-$(ls -dt store/*-arje-logind-compat 2>/dev/null | head -1)}"; [ -n "$ALC" ] && [ -d "$ALC" ]; then
|
||||
install -Dm755 "$ALC"/usr/bin/arje-logind-compat "$MERGED"/usr/bin/arje-logind-compat
|
||||
echo " ✓ $(basename "$ALC" | cut -c1-12)"
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user