Bugs en Xfce (1)

Antecedentes

Hace mucho tiempo (en realidad no hace ni un año), cuando Debian Wheezy todavía era testing y estaba congelada, había un bug muy tocapelotas en el entorno Xfce. El bug consistía en que, de vez en cuando, no se podían desmontar unidades externas como memorias o discos USB. Un power user podía usar sus 'superpoderes' para descubrir usando lsof o similares que era el demonio tumblerd (el generador de thumbnails) el que impedía desmontar el dispositivo. Matando esos procesos tumblerd enquistados se conseguía desmontarlo, pero la cuestión era por qué se quedaban bloqueados en primera instancia. Como algunos thumbnails de algunos videos no se generaban (fallaban), no era difícil deducir que ambos hechos estaban relacionados.

Este problema que para un usuario avanzado no era más que una incomodidad, para el average user podía ser un verdadero dolor de cabeza, así que lo reporté, o mejor dicho, lo confirmé en el bug report que ya existía: Bug #695353. Esperaba así evitar que Debian Wheezy saliera con un bug tan llamativo. Incluso mandaba un parche que parece que lo corregía en un bug similar que encontré en Launchpad. Si véis los mensajes, no se puede decir que me hicieran mucho caso. Debian Wheezy salió con ese bug, y no sé si aún permanece o fue corregido a posteriori, puesto que salté a Jessie/Testing poco después.

Como Wheezy tuvo una fase de freeze tan larga, la versión de Xfce con la que finalmente salió era la 4.8, mientras que por entonces el proyecto Xfce llevaba ya tiempo en la rama 4.10. En estos casos es habitual que upstream se niegue a corregir bugs de versiones anteriores, alegando que ya están arreglados en la versión estable, y ese trabajo recaiga sobre los hombros del mantenedor del paquete Debian. Pero ese no era el caso, ya que los mantenedores de los paquetes Debian (y Ubuntu/Xubuntu) son los propios desarrolladores de Xfce.

Nuevas versiones, nuevos problemas

Con la salida de Wheezy y el descongelamiento de testing, llegó Xfce 4.10 a nuestros repositorios, y con ello la nueva versión de tumbler 0.1.29 sustituyendo a la problemática y vieja 0.1.23. Sin embargo, como dice el adagio "nuevas versiones traen nuevos problemas"1, y aunque ya no había procesos tumbler congelados, el generador de thumbnails simplemente pasaba de generar thumbnails para video alguno.

En ese momento lo que pensé es que no habían conseguido averiguar cuál era el problema y simplemente habían decidido desactivar mientras tanto la generación de thumbnails de video. Dejé el tema pendiente, simplemente esperando que en algún momento entrara una acualización que lo arreglara.

Fue por casualidad que tiempo después, mirando otra cosa, encontrara esto en dmesg:

[ 9696.193804] pool[4896]: segfault at 40 ip 00007f7b9c5ab047 sp 00007f7b97bccc20 error 4 in tumbler-gst-thumbnailer.so[7f7b9c5a8000+5000]
[10307.656870] pool[4938]: segfault at 40 ip 00007f9906cc5047 sp 00007f99022e6c20 error 4 in tumbler-gst-thumbnailer.so[7f9906cc2000+5000]
[10461.865382] pool[5043]: segfault at 40 ip 00007f7d488c8047 sp 00007f7d43ee9c20 error 4 in tumbler-gst-thumbnailer.so[7f7d488c5000+5000]

La desaparición de los thumbnails no era obra del mantenedor del paquete, sino que ¡tumbler seguía haciendo de las suyas!

La investigación

Buscando el texto del error, descubrí que ya había sido reportado: Bug #713898. Así que añadí mi reporte. Pero como me pedían más información para poder perseguir el bug, me puse a investigar. Sé por experiencia que no hay nada más frustrante que tratar de cazar un bug sin nada a lo que agarrarse: es literalmente imposible.

Releyendo ahora el intercambio de mensajes con el mantenedor, me doy cuenta que él me estaba poniendo en la pista correcta. Pero eso lo sé ahora. En aquel momento, y tras mi anterior experiencia, estaba obcecado con tumbler, así que me descargué las fuentes y traté de echarles un vistazo. Viendo que aquello no me iba a llevar a ningún lado, me puse a investigar cómo funcionaban los thumbnails. Y aquí es cuando caemos por el agujero de la madriguera del conejo. Porque la generación de thumbnails en un sistema linux moderno es algo bastante más complejo de lo que uno pudiera pensar, e incluye entre otras cosas 3 servicios de D-Bus, además de una especificación freedesktop.org que define donde y cómo guardar los thumbnails2. Lo que además implica como prerrequisito conocer la especificación D-Bus. Genial.

Unas cuantas horas de lectura de especificaciones y estándares más tarde, más tiempo de buceo en Internet me llevan a un punto en el cual soy capaz de hacer debugging del servicio D-Bus de thumbnailing:

dbus-monitor --session --monitor interface=org.freedesktop.thumbnails.Thumbnailer1

pero los resultados son desalentadores: veo que el servicio no está funcionando como se espera, ya que los thumbnails de video que se solicitan por D-Bus nunca obtienen respuesta. Y no sé cómo montármelo para utilizar gdb en un plugin de un servicio que se invoca a través de D-BUS.

Desalentado, abandono en ese momento el bug. Llevo ya demasiado esfuerzo invertido en algo que sólo sirve para mostrar una minifoto de un video, y por delante sólo veo más y más tiempo desperdiciado.

El enfoque del asunto cambia radicalmente cuando hace mes y medio descubro que los mensajes de segfault han desaparecido. Revisando logs veo que no existen desde el 25 de agosto, y consultando /var/log/dpkg.log ese es el día en que se actualizan los paquetes de gstreamer. Le envío un mensaje al maintainter y le pido que cierre el bug, ya que los mensajes de error han desaparecido. Sin embargo, los thumbnails siguen sin generarse en mi sistema.

Persiguiendo al blanco equivocado

Hasta ese momento había estado echando las culpas a tumbler y su plugins, pero ahora mis sospechas empezaron a apuntar hacia el backend de video: Gstreamer.

No me voy a a parar mucho a contar el lío que hay montado con gstreamer, lo dejaré para una entrada para él solito, simplemente diré que hay dos versiones instaladas en paralelo, la 0.10 y la 1.0, y que cada versión tiene un juego de 3 conjuntos de plugins: good, bad y ugly (el bueno, el feo y el malo). Tumbler depende de las versiones 1.0, así que instalé los conjuntos de bad y ugly que me faltaban, y con eso conseguí que se generaran algunos (escasos) thumbnails para algunos videos. Pero la mayoría seguían sin funcionar.

La fortuna vino en mi ayuda poco despues: una actualización me recomendaba instalar gstreamer0.10-ffmpeg. No era la versión que yo necesitaba, pero no parecía existir nada equivalente para la 1.0. Pero lo que sí encontré, buscando por ffmpeg, fue:

$  aptitude search ffmpeg
...
p   ffmpegthumbnailer               - fast and lightweight video thumbnailer
p   ffmpegthumbnailer-dbg           - debugging informations for ffmpegthumbnail
p   ffmpegthumbs                    - video thumbnail generator using ffmpeg
...
p   libffmpegthumbnailer-dev        - development files for ffmpegthumbnailer
p   libffmpegthumbnailer4           - shared library for ffmpegthumbnailer

Y a partir de ahí, fue bastante sencillo descubrir el paquete tumbler-plugins-extra, que entre sus dependencias tiene estos paquetes, y que si se instala, todos los thumbnails de los videos empiezan a generarse. ¡Aleluya!

No se vayan todavía, aún hay más

Esperad un momento, ¿por qué este paquete no estaba instalado? Resulta que el paquete tumbler lo sugiere, pero no depende de él, y tampoco lo recomienda. Sólo puedo suponer que ffmpeg es un paquete "problemático" debido a las patentes de H.264, y se prefiere que no haya dependencias de ese tipo de paquetes.

¿Estaría pasando algo similar con gstreamer? Pues resulta que sí. Encontré que había herramientas para testear gstreamer en el paquete gstreamer1.0-tools3, y las utilicé para invocar uno de los ficheros de video que no generaban los thumbnails:

$ gst-launch-1.0 playbin uri=file:///home/user/a_video_file.mp4
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
Missing element: H.264 decoder
WARNING: from element
/GstPlayBin:playbin0/GstURIDecodeBin:uridecodebin0: No decoder available
for type 'video/x-h264, stream-format=(string)avc, alignment=(string)au,
level=(string)4, profile=(string)high, codec_data=(buffer)...,
width=(int)1280, height=(int)536, framerate=(fraction)24000/1001,
pixel-aspect-ratio=(fraction)1/1'.
Missing element: MPEG-4 AAC decoder
WARNING: from element
/GstPlayBin:playbin0/GstURIDecodeBin:uridecodebin0: No decoder available
for type 'audio/mpeg, mpegversion=(int)4, framed=(boolean)true,
stream-format=(string)raw, level=(string)2, base-profile=(string)lc,
profile=(string)lc, codec_data=(buffer)..., rate=(int)48000,
channels=(int)2'.
ERROR: from element
/GstPlayBin:playbin0/GstURIDecodeBin:uridecodebin0/GstDecodeBin:decodebin0:
Your GStreamer installation is missing a plug-in.

(he reducido la salida a las líneas realmente interesantes).

Como podéis observar, el problema está en los codecs para decodificar el fichero, que gstreamer no los encuentra. No están en bad ni en ugly (y por supuesto no están en good).

Por fortuna, el misterio quedó desvelado a la vez que miraba cómo usar las gstreamer-tools (se ve que no soy el primero en toparme con este problema): resulta que sí existe un paquete gstreamer 1.0 que engancha con ffmpeg. El problema es que no se llama ffmpeg ni nada parecido, se llama (¿ya habéis caído?) gstreamer1.0-libav. En el cisma ffmpeg/libav el mantenedor de Debian/Ubuntu está del lado de libav, y por lo tanto empaqueta libav. No sólo eso, en su guerra particular además parece que está intentando borrar toda mención a ffmpeg. El resultado es que se ha cambiado el nombre de los paquetes, pero sin que exista una transición via metapaquetes o paquetes virtuales como suele ser habitual en Debian.

TL;DR

En resumen, si no se te generan los thumbnails de videos en Xfce, tienes 2 formas de arreglarlo (asumiendo que tienes las últimas versiones de Debian Testing con las correcciones):

  • La vía gstreamer:

    aptitude install gstreamer1.0-plugins-bad
    aptitude install gstreamer1.0-plugins-ugly
    aptitude install gstreamer1.0-libav
    
  • La vía ffmpegthumbnailer:

    aptitude install tumbler-plugins-extra
    

Conclusiones

Aunque esta entrada ha quedado ya demasiado larga, me gustaría comentar una cosa antes de terminar, que además va a enganchar con la siguiente parte.

Uno de los problemas de reportar bugs es hacerlo sobre el componente que realmente está produciendo el bug. Como tenemos muchas capas desde el interfaz hasta el kernel, a veces es difícil determinar el culpable (cuando no es la conjunción de varios). No sólo eso, sino que tendemos a echarle la culpa al programa que está ante nuestros ojos, a veces con razón, a veces sin ella. Esto provoca que muchos reportes de bugs caigan en las interfaces gráficas como GNOME, KDE, o en este caso Xfce. Es lo que me ha pasado y me volverá a pasar (me temo) en otro bug que tengo abierto contra otro componente de Xfce.

Lo malo de la situación es que da la impresión de que el mantenedor no se preocupa demasiado de los bugs reportados. Al menos, esta es la sensación que tengo personalmente con Xfce. Cierto es que siendo tan pocos desarrolladores, estarán sobrecargados de trabajo. Pero no dejo de pensar que si a mí me cayeran encima muchos reportes de bugs de los que no tengo culpa, también terminaría siendo bastante escéptico, y salvo que hubiera buenas razones para pensar que fuera un problema de mi código, no le haría mucho caso. Me pongo en el lugar del mantenedor y lo comprendo, pero no deja de parecerme que hay un problema que repercute negativamente en todo el proceso.

No sé cómo se podría solucionar, y en realidad me parece que es sólo un aspecto más de un problema más general: la Quality Assurance y el mantenimiento y arreglo de errores en una distribución comunitaria, sobre la que habría que hablar largo y tendido (pero no aquí y ahora).

El fin del camino

Ha sido un camino bastante largo, pero en el transcurso he aprendido unas cuantas cosas sobre Debian, sobre la "fontanería" de los sistemas linux actuales, y sobre la naturaleza humana. No obstante, si este escrito ayuda a otro a que ese camino no sea tan largo y sinuoso, me doy por satisfecho.

Who were you, DenverCoder9? What did you see?!

:wq


  1. Vaaale, me lo acabo de inventar. Sin embargo, es un buen adagio. :-) 

  2. Que en el caso de Debian encima está mal, ya que se usa el directorio ~/.thumbnails, en vez de .cache/thumbnails que es el definido por la XDG Base Directory Specification

  3. Este corresponde a gstreamer 1.0, el de la 0.10 es gstreamer0.10-tools. 

blogroll

social