kde/qemu: MURO 2 caído — GBM_ALWAYS_SOFTWARE=1 y el escritorio PINTA
El segfault-139 de kwin en QEMU NO era llvmpipe ni el composite: diagnóstico por core dump + gdb del host (backtrace #0 0x0 ← dri2_initialize_drm ← eglInitialize ← EglDisplay::create ← DrmBackend::initialize; call *0x30(vtable swkmsMesaCoreExtension) = queryCompatibleRenderOnlyDeviceFd = NULL en el driver software). virtio-gpu-pci sin 3D expone un nodo KMS-only (no render-capable). En mesa 24.0.9 gbm sólo pone software=true vía dri_screen_create_sw, al que sólo se llega con GBM_ALWAYS_SOFTWARE o si dri_screen_create falla. Con MESA_LOADER_DRIVER_OVERRIDE kms_swrast, dri_screen_create tiene éxito ⇒ software=false ⇒ dri2_initialize_drm llama el vtable NULL ⇒ SIGSEGV. Fix: GBM_ALWAYS_SOFTWARE=1 en plasma-start. - plasma-start-qemu.sh: + GBM_ALWAYS_SOFTWARE=1 (el fix); + andamiaje de diagnóstico gated por DIAG=1 (logging kwin/mesa/egl verboso, stream vivo del kwin.log al serial, core dumps a /core + sync, sleep 3600 para congelar el serial). - run-qemu-desktop.sh (nuevo): run reproducible (DISP=none/gtk, TIMEOUT, VARS OVMF rw). - qemu-desktop-image.sh: restaurado bit +x. Verificado: headless (139=0, sin queryCompatible) y ventana gtk en DISPLAY=:0 — kwin_wayland + plasmashell + KSplash + kioworker vivos. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -30,6 +30,13 @@ export HOME=/root
|
||||
# --- render por software sobre virtio-gpu ---
|
||||
export LIBGL_ALWAYS_SOFTWARE=1
|
||||
export GALLIUM_DRIVER=llvmpipe
|
||||
# GBM_ALWAYS_SOFTWARE=1 — EL FIX del segfault (MURO 2, verificado en fuente mesa 24.0.9). virtio-gpu-pci
|
||||
# SIN 3D expone un nodo KMS-only (no render-capable). Con MESA_LOADER_DRIVER_OVERRIDE solo, gbm carga
|
||||
# kms_swrast pero deja gbm_dri->software=FALSE (dri_screen_create tiene éxito ⇒ nunca cae al fallback
|
||||
# dri_screen_create_sw, el único que setea software=true). Entonces dri2_initialize_drm entra al bloque
|
||||
# `if(!software)` y llama gbm_dri->mesa->queryCompatibleRenderOnlyDeviceFd() — NULL en el driver software
|
||||
# ⇒ SIGSEGV. GBM_ALWAYS_SOFTWARE=1 fuerza dri_screen_create_sw ⇒ software=true ⇒ se salta ese bloque.
|
||||
export GBM_ALWAYS_SOFTWARE=1
|
||||
# kms_swrast (NO swrast): kwin abre card0 como dispositivo KMS y crea un gbm device sobre él ⇒ necesita
|
||||
# el driver de software para KMS (dumb buffers). Con 'swrast' a secas gbm_create_device falla ("Failed
|
||||
# to create gbm device"). kms_swrast_dri.so está en /usr/lib/dri.
|
||||
@@ -49,6 +56,18 @@ export QT_QPA_PLATFORM=wayland
|
||||
export QT_QPA_PLATFORMTHEME=kde
|
||||
export QT_QPA_FONTDIR=/usr/share/fonts/dejavu
|
||||
|
||||
# --- DIAGNÓSTICO del segfault-al-1er-composite (MURO 2) ---
|
||||
# Sin gdb en la imagen: subimos el logging categorizado de kwin (kwin_core/drm/scene/opengl) + mesa/egl
|
||||
# para ver EN QUÉ FASE muere (bind EGL, alloc GBM, JIT llvmpipe, o el paint real). DIAG=0 para apagarlo.
|
||||
if [ "${DIAG:-1}" = 1 ]; then
|
||||
export QT_LOGGING_RULES="kwin_*=true;qt.qpa.*=true"
|
||||
export EGL_LOG_LEVEL=debug
|
||||
export LIBGL_DEBUG=verbose
|
||||
export MESA_DEBUG=1
|
||||
export GALLIUM_HUD= # no HUD, sólo para dejar constancia
|
||||
export KWIN_DRM_DEBUG=1
|
||||
fi
|
||||
|
||||
mkdir -p "$XDG_RUNTIME_DIR" "$XDG_CONFIG_HOME" "$XDG_CACHE_HOME" /run/dbus /root
|
||||
chmod 700 "$XDG_RUNTIME_DIR"
|
||||
[ -s /etc/machine-id ] || cat /proc/sys/kernel/random/uuid 2>/dev/null | tr -d - > /etc/machine-id
|
||||
@@ -76,10 +95,24 @@ if [ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ]; then
|
||||
fi
|
||||
say "dbus: ${DBUS_SESSION_BUS_ADDRESS:-NO ARRANCO}"
|
||||
|
||||
# --- CORE DUMP del segfault (MURO 2): sin gdb en la imagen, sacamos un core y lo leemos con el gdb del
|
||||
# host apuntando al rootfs fundido. Localiza el frame culpable (libLLVM/llvmpipe vs kwin vs mesa). ---
|
||||
if [ "${DIAG:-1}" = 1 ]; then
|
||||
ulimit -c unlimited 2>/dev/null || true
|
||||
# /core en la RAÍZ ext4 (NO /tmp: es tmpfs=RAM y se pierde al matar QEMU). Tras el crash hacemos sync
|
||||
# explícito ⇒ el core persiste en la imagen aunque después mate QEMU con SIGKILL.
|
||||
echo '/core.%e.%p' > /proc/sys/kernel/core_pattern 2>/dev/null || true
|
||||
say "core dumps ON (pattern=$(cat /proc/sys/kernel/core_pattern 2>/dev/null), ulimit -c=$(ulimit -c))"
|
||||
fi
|
||||
|
||||
# Compositor sobre el DRM de virtio (software EGL/GBM vía kms_swrast). SIN --virtual: presenta al display.
|
||||
say "lanzando kwin_wayland (DRM virtio, software GL)..."
|
||||
/usr/bin/kwin_wayland --drm >/tmp/kwin.log 2>&1 &
|
||||
KWIN=$!
|
||||
# stream EN VIVO del kwin.log al serial: el volcado post-mortem se trunca porque el getty respawnea y
|
||||
# pisa el serial ⇒ con tail -f la última línea antes del segfault llega al host pase lo que pase.
|
||||
( tail -f /tmp/kwin.log 2>/dev/null | sed -u 's/^/kwin> /' > /dev/ttyS0 2>/dev/null ) &
|
||||
TAILPID=$!
|
||||
i=0
|
||||
while [ $i -lt 60 ]; do
|
||||
[ -S "$XDG_RUNTIME_DIR/wayland-0" ] && break
|
||||
@@ -104,6 +137,15 @@ say "procesos: $(ps axo comm 2>/dev/null | grep -E 'kwin|plasma' | sort -u | tr
|
||||
say "escritorio arriba (o mira /tmp/plasmashell.log). Ctrl-C mata la sesion."
|
||||
dump /tmp/plasmashell.log
|
||||
wait $KWIN
|
||||
RC=$?
|
||||
# kwin salió ⇒ volcá su log para saber por qué (backend QPainter, DRM, modeset…)
|
||||
say "kwin salió (código $?) — volcando kwin.log:"
|
||||
say "kwin salió (código $RC) — volcando kwin.log:"
|
||||
dump /tmp/kwin.log
|
||||
# copiar los logs a la ext4 raíz y SYNC ⇒ core + logs persisten en la imagen para leer desde el host
|
||||
# con debugfs/gdb (el SIGKILL de QEMU no sincroniza; sin este sync se pierde todo lo de esta sesión).
|
||||
cp /tmp/kwin.log /kwin.log 2>/dev/null || true
|
||||
cp /tmp/plasmashell.log /plasmashell.log 2>/dev/null || true
|
||||
say "cores en /: $(ls -la /core.* 2>/dev/null | tr '\n' ' ' || echo NINGUNO)"
|
||||
sync; sync
|
||||
say "== disco SYNCED (core+logs en la raíz). serial CONGELADO. matá QEMU desde el host. =="
|
||||
sleep 3600
|
||||
|
||||
Regular → Executable
Executable
+54
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env bash
|
||||
# run-qemu-desktop.sh — arranca la imagen KDE en QEMU (virtio-gpu + software GL) de forma REPRODUCIBLE.
|
||||
# Antes era un comando ad-hoc. Por defecto headless (DISPLAY=none) para diagnóstico por serial sin
|
||||
# interferir con la sesión mirada del laptop; DISP=gtk para ver la ventana (necesita DISPLAY=:0 Xwayland,
|
||||
# y cada restart de mirada mata la ventana).
|
||||
#
|
||||
# scripts/kde/run-qemu-desktop.sh # headless, serial → work/qemu-desktop-serial.log
|
||||
# DISP=gtk scripts/kde/run-qemu-desktop.sh # ventana gráfica (virtio-gpu por gtk)
|
||||
# TIMEOUT=90 scripts/kde/run-qemu-desktop.sh # mata QEMU a los 90s (diagnóstico automático)
|
||||
set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
|
||||
|
||||
IMG="${IMG:-work/hammer-kde-qemu.img}"
|
||||
SERIAL="${SERIAL:-work/qemu-desktop-serial.log}"
|
||||
OVMF_CODE="${OVMF_CODE:-/usr/share/edk2/x64/OVMF_CODE.4m.fd}"
|
||||
OVMF_VARS_SRC="${OVMF_VARS_SRC:-/usr/share/edk2/x64/OVMF_VARS.4m.fd}"
|
||||
VARS="${VARS:-work/qemu-desktop-OVMF_VARS.fd}"
|
||||
DISP="${DISP:-none}"
|
||||
MEM="${MEM:-4G}"
|
||||
SMP="${SMP:-4}"
|
||||
|
||||
[ -r "$IMG" ] || { echo "falta $IMG — corré scripts/kde/qemu-desktop-image.sh" >&2; exit 1; }
|
||||
[ -r "$OVMF_CODE" ] || { echo "falta OVMF_CODE ($OVMF_CODE)" >&2; exit 1; }
|
||||
# copia escribible de las VARS (pflash necesita rw; la del sistema es read-only)
|
||||
[ -r "$VARS" ] || cp "$OVMF_VARS_SRC" "$VARS"
|
||||
|
||||
case "$DISP" in
|
||||
gtk) DISPLAY_ARGS=(-display gtk -device virtio-gpu-pci) ;;
|
||||
none) DISPLAY_ARGS=(-display none -device virtio-gpu-pci) ;;
|
||||
*) DISPLAY_ARGS=(-display "$DISP" -device virtio-gpu-pci) ;;
|
||||
esac
|
||||
|
||||
# serial nuevo cada corrida (el diagnóstico depende de que no se mezcle con boots viejos)
|
||||
: > "$SERIAL"
|
||||
|
||||
QEMU_ARGS=(
|
||||
-machine q35 -accel kvm -cpu host
|
||||
-m "$MEM" -smp "$SMP"
|
||||
-drive if=pflash,format=raw,unit=0,file="$OVMF_CODE",readonly=on
|
||||
-drive if=pflash,format=raw,unit=1,file="$VARS"
|
||||
-drive file="$IMG",format=raw,if=virtio
|
||||
"${DISPLAY_ARGS[@]}"
|
||||
-serial "file:$SERIAL"
|
||||
-no-reboot
|
||||
)
|
||||
|
||||
echo "==> QEMU (DISP=$DISP, serial=$SERIAL)"
|
||||
echo " imagen: $IMG"
|
||||
if [ -n "${TIMEOUT:-}" ]; then
|
||||
echo " TIMEOUT=${TIMEOUT}s (auto-kill)"
|
||||
exec timeout --signal=KILL "${TIMEOUT}" qemu-system-x86_64 "${QEMU_ARGS[@]}"
|
||||
else
|
||||
exec qemu-system-x86_64 "${QEMU_ARGS[@]}"
|
||||
fi
|
||||
Reference in New Issue
Block a user