Development/Tutorials/Debugging/How to create useful crash reports (es): Difference between revisions

From KDE TechBase
 
(26 intermediate revisions by the same user not shown)
Line 5: Line 5:
==Cómo crear informes de fallos útiles==
==Cómo crear informes de fallos útiles==


Un buen informe de fallos en Bugzilla consiste de dos partes:
Un buen informe de fallos en [http://bugs.kde.org Bugzilla] consiste de dos partes:
* Una descripción de cómo reproducir el fallo, y
* Una <b>descripción de cómo reproducir el fallo</b>, y
* una pila de las últimas funciones ejecutadas (backtrace en inglés) en el momento del fallo.
* una <b>pila de las últimas funciones ejecutadas</b> (backtrace en inglés) en el momento del fallo.


Si falla uno de estos elementos, se vuelve mucho más dificil, si no imposible, resolver el problema a los desarrolladores.
Si falla uno de estos elementos, se vuelve mucho más dificil, si no imposible, resolver el problema a los desarrolladores.
Line 15: Line 15:
Hay un artículo sobre cómo escribir buenos informes de fallos [http://www.chiark.greenend.org.uk/~sgtatham/bugs-es.html en este enlace], por favor, leálo antes de informar sobre fallos.
Hay un artículo sobre cómo escribir buenos informes de fallos [http://www.chiark.greenend.org.uk/~sgtatham/bugs-es.html en este enlace], por favor, leálo antes de informar sobre fallos.


No adjunte la pila de las últimas funciones ejecutas al informe, simplemente péguelo en el. De este modo es mucho más fácil buscar informes duplicados, porque no se busca en los adjuntos.
No adjunte la pila de las últimas funciones ejecutadas al informe, simplemente péguelo en el. De este modo es mucho más fácil buscar informes duplicados, porque no se busca en los ficheros adjuntos.


Al pegar la pila de las últimas funciones ejecutadas, elimine la mayoría de las líneas


If you paste a backtrace to a report, make sure you strip all but one or two of the
(no debugging symbols found)


(no debugging symbols found)
excepto una o dos de cada bloque, porque lo hacen más dificil de leer.


lines from the backtrace as they make it harder to read.
Aunque pegar la pila de las últimas funciones ejecutadas directamente al informe se prefiere a añadirlo como adjunto, por favor, no haga lo mismo con otra información como trazas (valgrind, strace o salida del terminal) o datos de ejemplo (correos, ficheros HTML,...), utilize ficheros adjuntos para esos datos.


Even though pasting backtraces directly is preferred over adding an attachment, please do not paste other things like logs (valgrind, strace or terminal output) or example data (mails, HTML files and so on). Use attachments for these items.
===pila de las últimas funciones ejecutadas===
===pila de las últimas funciones ejecutadas===


Backtraces are essential. They may look meaningless to you, but they might actually contain a wealth of useful information. A backtrace describes which functions were called prior to the crash, so that developers may track down in which function the mess started. Having good backtraces has a downside: libraries and executables occupy much more disk space than their optimized counter parts. That's the reason why many distros choose to install stripped files, which results in useless backtraces:
La pila de las últimas funciones ejecutadas, aunque pueda parecer un galimatías, contiene información muy valiosa para los desarrolladores. Estas pilas describen qué funciones se llamaron justo en el momento del fallo, así que los desarrolladores puede saber qué funciones son las culpables del fallo. Pero tener buenas pilas tiene un lado negativo, los ejecutables y bibliotecas que se utilizan ocupan mucho más espacio en disco que sus equivalentes optimizados. Por esta razón la mayoría de las distribuciones elijen instalar ejecutables sin símbolos de depuración (stripped en inglés), que '''producen pilas de últimas funciones ejecutadas inservibles''':


(no debugging symbols found)
(no debugging symbols found)
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
[Thread debugging using libthread_db enabled]
[Thread debugging using libthread_db enabled]
[New Thread -1233848624 (LWP 12212)]
[New Thread -1233848624 (LWP 12212)]
[New Thread -1255081072 (LWP 12820)]
[New Thread -1255081072 (LWP 12820)]
[New Thread -1240921200 (LWP 12819)]
[New Thread -1240921200 (LWP 12819)]
[New Thread -1266680944 (LWP 12818)]
[New Thread -1266680944 (LWP 12818)]
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
0xffffe410 in __kernel_vsyscall ()
0xffffe410 in __kernel_vsyscall ()
#0  0xffffe410 in __kernel_vsyscall ()
#0  0xffffe410 in __kernel_vsyscall ()
#1  0xb6a1210b in ?? () from /lib/tls/i686/cmov/libpthread.so.0
#1  0xb6a1210b in ?? () from /lib/tls/i686/cmov/libpthread.so.0
#2  0xb6a85afe in ?? () from /usr/lib/libX11.so.6
#2  0xb6a85afe in ?? () from /usr/lib/libX11.so.6
#3  0x00000003 in ?? ()
#3  0x00000003 in ?? ()
#4  0x082149c0 in ?? ()
#4  0x082149c0 in ?? ()
#5  0x00003ffc in ?? ()
#5  0x00003ffc in ?? ()
#6  0x00000000 in ?? ()
#6  0x00000000 in ?? ()


But no worries, with some modifications you can create full blown backtraces for KDE applications.
Pero no todo está perdido, con algunas pequeñas modificaciones se pueden crear pilas de las últimas funciones ejecutadas con toda la información  necesaria para los desarrolladores de KDE.


===Preparando los paquetes KDE===
===Preparando los paquetes KDE===


If your distribution has debugging-enabled packages, install them.
Si su distribución tiene paquetes de depuración (debug), instálelos.


It is easy to see which debug packages you are missing from looking at the backtrace. For example, take the following line from a backtrace:
Es fácil saber qué paquetes depuración hacen falta mirando la pila de las últimas funciones ejecutadas. Por ejemplo, de una línea como la siguiente:


#6  0xb7975bdc in ?? () from /usr/lib/libkmailprivate.so.4
#6  0xb7975bdc in ?? () from /usr/lib/libkmailprivate.so.4


The ?? indicates that the library libkmailprivate.so.4 does not have debug information, which might be available in separate debug packages. In this case, it is pretty easy to guess that you need to install debug packages for KMail to get a better backtrace.
El ?? indica que la biblioteca libkmailprivat.so.4 no tiene información de depuración, que puede estar disponible en paquetes de depuración separados. En este caso, es bastante fácil averiguar que necesita instalar los paquetes de depuración de KMail para obtener una pila con información útil.


Sometimes, you need to install more than one debug package to get a good backtrace. This depends on how the distribution splits up the packages. For example, for some distributions it is enough to install the debug package for kdepim to get enough debugging information for a crash in KMail, for other distributions there is an additional debug package just for KMail.
A veces, necesitará instalar más de un paquete de depuración para obtener una buena pila. Esto depende de cómo su distribución divida los paquetes. Por ejemplo, en algunas distribuciones es suficiente instalar el paquete de depuración para kdepim para obtener suficiente información para un casque en KMail, para otras distribuciones hay un paquete de depuración adicional para KMail.


Here's a list of how to obtain debug packages for some distributions:
Aquí hay una lista de cómo obtener paquetes de depuración para algunas distribuciones:


    * Debian - Debian offers -dbg packages to easy create useful backtraces. Just install the corresponding -dbg package. e.g. kdepim-dbg for KMail crashes. The dependencies of -dbg makes sure to pull in the other right packages (kdelibs-dbg, gdb, and so on).
*'''Debian''' - Debian ofrece paquetes <tt>-dbg</tt> para facilitar la tarea de crear pilas útiles. Al instalar el paquete de depuración correspondiente <tt>-dbg</tt>, por ejemplo <tt>kdepim-dbg</tt> para casques de KMail, las dependencias de los paquetes hacen que se instalen todos los paquetes necesarios y en el orden correcto (kdelibs-dbg, gdb, ...).
    * FreeBSD ports - Please refer to the KDE on FreeBSD FAQ.
<!--*'''Fedora''' ???-->
    * Gentoo - Gentoo has its own document describing how to proceed.
*'''FreeBSD ports''' - Por favor, mire en [http://freebsd.kde.org/faq.php#AKDEapplicationcrashedandIwanttofileabugreportathttpbugskdeorgbutthebacktraceintheKDECrashManagerisuselessWhatcanIdo KDE las preguntas más frecuentes de FreeBSD].
    * Mandriva - Mandriva 2007.0 and up has additional debugging packages for all of KDE (in fact, for all of its packages). Just install the corresponding -debug package, like kdebase-debug and kdemultimedia-debug. You probably want to install kdelibs-debug anyways.
*'''Gentoo''' - Gentoo tiene su [http://www.gentoo.org/proj/en/qa/backtraces.xml propio documento (en inglés)] describiendo cómo proceder.
          o Note: the -debug packages are in separate repositories. For instance, for all packages in main, you'll find the debugging package in repository debug_main.  
*'''Mandriva''' - Mandriva 2007.0 y posteriores tienen paquetes adicionales de depuración para todos sus paquetes (incluyendo KDE). Sólo hay que instalar el paquete correspondiente <tt>-debug</tt>, como <tt>kdebase-debug</tt> y <tt>kdemultimedia-debug</tt>. También debería instalar <tt>kdelibs-debug</tt>.
    * Kubuntu/Ubuntu - The Ubuntu family makes things quite easy. Every official KDE module has an additional package in the repository, suffixed with -dbg. Always install kdelibs5-dbg, because all KDE applications use kdelibs (kdelibs-dbg for KDE 3 applications). Then you should install a -dbg package for the application which crashed. For example if KOrganizer crashed you should install kdepim-dbg as well. If the program is not from an official KDE module and has no -dbg package, you can install the -dbgsym package from the repository listed on this Debugging Program Crashes page.
** Note: Los paquetes <tt>-debug</tt> están en repositorios separados. Por ejemplo, para todos los paquetes en <tt>main</tt>, encontrará los paquetes de depuración en el repositorio <tt>debug_main</tt>.
    * openSUSE - You should only install the -debuginfo packages, for example: kdepimlibs4-debuginfo. You can find these packages in KDE repositories. There is also a dedicated openSUSE debugging page.
*'''Kubuntu/Ubuntu''' - Las distribuciones Ubuntu hacen estas cosas fáciles. Cada paquete oficial KDE tiene un paquete adicional en el repositorio, con el sufijo <tt>-dbg</tt>. Siempre hay que instalar  <tt>kdelibs5-dbg</tt>, porque todas las aplicaciones KDE utilizan kdelibs (kdelibs-dbg para las aplicaciones KDE 3). Luego debería instalar el paquete -dbg para la aplicación que falló. Por ejemplo, si falló KOrganizer, debería instalar <tt>kdepim-dbg</tt>. Si el programa no es un módulo oficial KDE y no tiene paquete -dgb, puede instalar el paquete -dbgsym desde el repositorio listado en su página [https://wiki.kubuntu.org/DebuggingProgramCrash Debugging Program Crashes].
    * Fedora - Fedora has its own document describing how to proceed. (A debuginfo repository has to be enabled.)  
*'''openSUSE''' - Sólo hay que instlar los paquetes  <tt>-debuginfo</tt>, por ejemplo: <tt>kdepimlibs4-debuginfo</tt>. Se pueden encontrar estos paquetes en [http://en.opensuse.org/KDE/Repositories los repositorios KDE]. También tiene una página dedicada a [http://es.opensuse.org/Bugs:An_application_crashed la depuración].
*'''Fedora''' - Fedora has its [http://fedoraproject.org/wiki/StackTraces own document] describing how to proceed. (A debuginfo repository has to be enabled.)


If your distribution doesn't have debugging-enabled packages for KDE, you'll have to compile KDE from sources:
Si su distribución no incluye paquetes de depuración para KDE, tendría que compilar KDE desde el código fuente:


    * If you're using KDE 3, then at the configure stage, you should supply the parameter --enable-debug=full in order to build debug symbols in the resulting files.
* Si está usando KDE3, entonces en la etapa de configuración, debería añadir el parámetro <tt>--enable-debug=full</tt> para obtener símbolos de depuración en los ficheros resultantes.
    * If you're using KDE 4, then at the cmake stage, you should supply the parameter -DCMAKE_BUILD_TYPE=debugfull. If you want to specify your own CXXFLAGS, then use -DCMAKE_BUILD_TYPE=None CMAKE_CXX_FLAGS="-O0 -g". You can change the CMAKE_CXX_FLAGS as appropriate for your needs.  
* Si está usando KDE4, entonces en la etapa cmake, debe añadir el parámetro <tt>-DCMAKE_BUILD_TYPE=debugfull</tt>. Si quiere especificar sus propios CXXFLAGS, entonces utilize <tt>-DCMAKE_BUILD_TYPE=None CMAKE_CXX_FLAGS="-O0 -g"</tt>. Puede cambiar los CMAKE_CXX_FLAGS para que se ajuste a sus necesidades.


Then it's just make and make install as you're used to.
Luego son los conocidos <tt>make</tt> y <tt>make install</tt> habituales.
[edit] Crash!


Now it's time to crash your application. The KDE Crash Dialog should appear right after the crash, which shows the Backtrace tab.
===Crash!===
KDE Crash Dialog


Click that tab and wait for a minute. This process may take quite some memory, so things may go sluggish all of a sudden. But the result should look much better. For example:
Ahora, a hacer fallar la aplicación de nuevo (una buena forma de tener una excelente descripción de cómo reproducir el fallo). El diálogo de aplicación fallida debería aparecer después del fallo, mostrando la pila de últimas funciones ejecutadas.


Using host libthread_db library "/lib/libthread_db.so.1".
<!--TODO: Actualizar a KDE4 -->
[Thread debugging using libthread_db enabled]
[New Thread -1232783168 (LWP 7604)]
[KCrash handler]
#6  0x0806be76 in TreeMapItem::parent (this=0x0)
    at /home/bram/KDE/kde3/kdeaddons/konq-plugins/fsview/treemap.h:285
#7  0x08065fea in TreeMapItemList::compareItems (this=0xbfec04a8, item1=0x0,
    item2=0x0)
    at /home/bram/KDE/kde3/kdeaddons/konq-plugins/fsview/treemap.cpp:720
#8  0xb7281619 in QGList::operator== () from /usr/qt/3/lib/libqt-mt.so.3
#9  0x0806d498 in QPtrList<TreeMapItem>::operator== (this=0xbfec04a8,
    list=@0xbfec0468) at /usr/qt/3/include/qptrlist.h:74
#10 0x08062e18 in TreeMapWidget::mousePressEvent (this=0xbfec03ac,
    e=0xbfebff1c)
    at /home/bram/KDE/kde3/kdeaddons/konq-plugins/fsview/treemap.cpp:1840
#11 0xb7004a63 in QWidget::event () from /usr/qt/3/lib/libqt-mt.so.3
#12 0xb6f6bca7 in QApplication::internalNotify ()
  from /usr/qt/3/lib/libqt-mt.so.3
#13 0xb6f6ca88 in QApplication::notify () from /usr/qt/3/lib/libqt-mt.so.3
#14 0xb7725a84 in KApplication::notify (this=0xbfec055c, receiver=0xbfec03ac,
    event=0xbfebff1c)
    at /home/bram/KDE/kde3/kdelibs/kdecore/kapplication.cpp:550
#15 0xb6f0bfd2 in QETWidget::translateMouseEvent ()
  from /usr/qt/3/lib/libqt-mt.so.3
#16 0xb6f0b8b0 in QApplication::x11ProcessEvent ()
  from /usr/qt/3/lib/libqt-mt.so.3
#17 0xb6f1b761 in QEventLoop::processEvents () from /usr/qt/3/lib/libqt-mt.so.3
#18 0xb6f82831 in QEventLoop::enterLoop () from /usr/qt/3/lib/libqt-mt.so.3
#19 0xb6f826b6 in QEventLoop::exec () from /usr/qt/3/lib/libqt-mt.so.3
#20 0xb6f6b72f in QApplication::exec () from /usr/qt/3/lib/libqt-mt.so.3
#21 0x0805181e in main (argc=134673960, argv=0xffffffff)
    at /home/bram/KDE/kde3/kdeaddons/konq-plugins/fsview/main.cpp:55


This looks better, right? It shows memory addresses, the source files and line numbers and the parameters passed to functions. Which make it more helpful to the developer where to look for the problem.
[[Image:Kde crash dialog1.png|center|300px|KDE Crash Dialog]]


Pulse en la pestaña Backtrace y espere un buen rato, el proceso puede ocupar muchar memoria y mucho procesador, así que el resto de procesos pueden ralentizarse mucho. Pero el resultado debe ser ahora muchísimo mejor, por ejemplo:


Note
Using host libthread_db library "/lib/libthread_db.so.1".
noframe
[Thread debugging using libthread_db enabled]
You need GDB installed to get the backtrace of a crash. Please read the next section to know what GDB is, and how to install it.
[New Thread -1232783168 (LWP 7604)]
[KCrash handler]
#6  0x0806be76 in TreeMapItem::parent (this=0x0)
    at /home/bram/KDE/kde3/kdeaddons/konq-plugins/fsview/treemap.h:285
#7  0x08065fea in TreeMapItemList::compareItems (this=0xbfec04a8, item1=0x0,
    item2=0x0)
    at /home/bram/KDE/kde3/kdeaddons/konq-plugins/fsview/treemap.cpp:720
#8  0xb7281619 in QGList::operator== () from /usr/qt/3/lib/libqt-mt.so.3
#9  0x0806d498 in QPtrList<TreeMapItem>::operator== (this=0xbfec04a8,
    list=@0xbfec0468) at /usr/qt/3/include/qptrlist.h:74
#10 0x08062e18 in TreeMapWidget::mousePressEvent (this=0xbfec03ac,
    e=0xbfebff1c)
    at /home/bram/KDE/kde3/kdeaddons/konq-plugins/fsview/treemap.cpp:1840
#11 0xb7004a63 in QWidget::event () from /usr/qt/3/lib/libqt-mt.so.3
#12 0xb6f6bca7 in QApplication::internalNotify ()
    from /usr/qt/3/lib/libqt-mt.so.3
#13 0xb6f6ca88 in QApplication::notify () from /usr/qt/3/lib/libqt-mt.so.3
#14 0xb7725a84 in KApplication::notify (this=0xbfec055c, receiver=0xbfec03ac,  
    event=0xbfebff1c)
    at /home/bram/KDE/kde3/kdelibs/kdecore/kapplication.cpp:550
#15 0xb6f0bfd2 in QETWidget::translateMouseEvent ()
    from /usr/qt/3/lib/libqt-mt.so.3
#16 0xb6f0b8b0 in QApplication::x11ProcessEvent ()
    from /usr/qt/3/lib/libqt-mt.so.3
#17 0xb6f1b761 in QEventLoop::processEvents () from /usr/qt/3/lib/libqt-mt.so.3
#18 0xb6f82831 in QEventLoop::enterLoop () from /usr/qt/3/lib/libqt-mt.so.3
#19 0xb6f826b6 in QEventLoop::exec () from /usr/qt/3/lib/libqt-mt.so.3
#20 0xb6f6b72f in QApplication::exec () from /usr/qt/3/lib/libqt-mt.so.3
#21 0x0805181e in main (argc=134673960, argv=0xffffffff)
    at /home/bram/KDE/kde3/kdeaddons/konq-plugins/fsview/main.cpp:55


Parece mucho mejor, ¿verdad? Muestra a los desarrolladores las direcciones de memoria, los ficheros fuente y los números de línea, además de los parámetros pasados a las funciones. Así es mucho más facil resolver el fallo.
{{note|Se '''necesita''' tener instalado GDB para obtener las pilas de las últimas funciones ejecutadas en un fallo. Mire la siguiente sección para saber qué es GDB y como instalarlo.}}


===Obteniendo la pila de las últimas funciones ejecutadas con GDB===
===Obteniendo la pila de las últimas funciones ejecutadas con GDB===


En algunos casos, no es posible crear la pila de las últimas funciones ejecutadas dentro del diálogo de aplicación caida del KDE. Esto puede ser porque una aplicacón entró en un bucle sin fin, o el diálogo de aplicación caída no aparece por algún motivo.
En algunos casos, no es posible crear la pila de las últimas funciones ejecutadas dentro del diálogo de aplicación fallida del KDE. Esto puede ser porque una aplicacón entró en un bucle sin fin, o el diálogo de aplicación fallida no aparece por algún motivo.
Siempre puede intentar obtener la instantánea de donde aparece el fallo con gdb, el depurador GNU. GDB está disponible para instalarse en la inmensa mayoría de las distribuciones en su almacén de programas.
Siempre puede intentar obtener la instantánea de donde aparece el fallo con <tt>gdb</tt>, [http://sourceware.org/gdb/ el depurador GNU ]. GDB está disponible para instalarse en la inmensa mayoría de las distribuciones en su almacén de programas.


Invoking GDB differs from the situation. You can run an application from inside gdb, or attach gdb to an already running process. The latter may be useful when an application already has entered an infinite loop. But we will first start with running an application inside gdb. From the shell, run:
Hay dos formas de utilizar GDB:
* iniciar una aplicación dentro de gdb, o
* depurar una aplicación que ya está funcionando, útil en el caso de una aplicación que se encuentra en un bucle sin fin.


$ gdb someKDEapp
Primero empezaremos por iniciar una aplicación dentro de gdb.
Desde el terminal, ejecutamos:


The GDB prompt will appear. Note that this does not start the application itself, you should run it by invoking the run command:
$ gdb someKDEapp


(gdb) run
La línea de comandos del GDB aparecerá. Todavía no se ha iniciado la aplicación, para ello hay que invocar el comando run:


This will run the application like you are used to, and you can work with it like normal (it only consumes far more memory and may feel sluggish). Now it's time to reproduce your crash. When you succeed, the application just closes and you should return to your GDB prompt. Now it's time to run the 'backtrace' command:
(gdb) run


Esto iniciará la aplicación como de costumbre, y se puede trabajar con ella de forma normal (sólo consume mucha más memoria que de costumbre y puede ir un poco más lenta de lo normal). Ahora, a reproducir el fallo. Cuando se tenga éxito, la aplicación se cerrará y debería estar en la línea de comandos del GDB. Ahora a mostrar la pila (backtrace en inglés):


Note
{{note|Algunas aplicaciones KDE (como JuK y KTorrent) sólo permiten iniciar la aplicación una vez. Para estos casos, habría que escribir "run --nofork" en la línea de comandos del gdb en lugar de "run", o gdb intentará depurar el proceso incorrecto. Si no está seguro de cuándo debe utlizar --nofork, simplemente úselo. Si la aplicación dice que es una opción desconocida, entondes debe quitar el --nofork.}}
noframe
Some KDE applications (such as JuK and KTorrent) have special code to ensure that there is only one running instance of the application at a time. For these applications you should type in "run --nofork" at the (gdb) prompt instead of "run" because otherwise gdb will try to debug the wrong process. If you are unsure as to whether to use --nofork just try it. If the application says it's an unknown option you can remove --nofork.
 


(gdb) thread apply all backtrace
(gdb) thread apply all backtrace


This should give a good backtrace which can be posted at the KDE Bugzilla.
Esto debería dar una pila de las últimas funciones ejecutadas que puede ser pegado en el [http://bugs.kde.org Bugzilla de KDE].
 
In case you want to attach to an existing process, run the following command in the shell:


$ gdb someKDEapp pid
En el caso de depurar una aplicación ya iniciada, ejecute el siguiente comando en el terminal:


where pid is the process ID of the process you want to attach to. Once attached, and the process is in an infinite loop, after using the 'backtrace' command again a useful backtrace will appear. You can use 'continue' command to let the application run again and press Ctrl+C in gdb to be able to again enter commands.
$ gdb la_aplicación_KDE pid
[edit] Retrieving a backtrace with Valgrind


When it comes to crashes, Valgrind is also a useful tool to create a backtrace. It's not a substitution for GDB, but rather a supplement.
donde ''pid'' es el IDentificador del proceso que se quiere depurar. Una vez que se ha enganchado, si el proceso está en bucle sin fin, después de utilizar el comando gdb 'backtrace' aparecerá una pila de las últimas funciones ejecutadas util. Después se puede utilizar el comando gdb 'continue' para dejar que la aplicación siga ejecutándose y pulsando Ctrl+C en gdb permitirá de nuevo introducir comandos.


When you run an application in valgrind, every piece of memory read or written by the application is being checked. Valgrind will report erroneous memory operations in the standard output or in a log file. Since most crashes are due to an invalid memory read, valgrind can be useful to track down where the problem occurs.
===Obteniendo la pila de las últimas funciones ejecutadas con Valgrind===


Cuando se trata de fallos, [http://www.valgrind.org Valgrind] es también una herramienta muy útil para crear pilas de las últimas funciones ejecutadas. No es un sustituto del GDB, sino un suplemento.


Note
Cuando se inicia una apliación en valgrind, cada operación de  memoria del proceso se comprueba. Valgrind generará un informe de operaciones de memoria incorrectas del proceso por la salida estándard o en fichero de trazas. Como la mayoría de los fallos se deben a la lectura de la memoria del proceso incorrecta, valgrind es muy útil para rastrear dónde ocurre el fallo.
noframe
Valgrind consists of several tools in order to check or profile an application. For this article, we only use memcheck, the default tool when valgrind is being invoked.


{{note|Valgrind contiene varias herramientas para probar o perfilar una aplicación. Para este artículo, sólo utilizamos memcheck, la herramienta por defecto cuando valgrind se invoca.}}


Like GDB, Valgrind makes running an application much slower, while consuming a lot more resources.
Como GDB, Valgrind utiliza mucha más memoria y hace que la aplicación funcione mucho más despacio.


Start the application within valgrind:
Para iniciar la aplicación con valgrind:


$ valgrind --log-file=someKDEapp someKDEapp
$ valgrind --log-file=la_aplicación_KDE_a_depurar la_aplicación_KDE_a_depurar


Now reproduce the crash. As soon as this happens, the application and valgrind will terminate. What's left is a file named someKDEapp.pid where pid is replaced by the process ID of the valgrind process. The file may list more errors than the one causing the crash. Here's the bit causing the crash which corresponds to the GDB backtrace above:
Ahora, el reproducir el fallo, la aplicación y valgrind acabarán. Lo que queda es un fichero llamado <tt>la_aplicación_KDE_a_depurar.pid</tt> donde ''pid'' se sustituye por el ID del proceso de valgrind. Este fichero puede contener más errores que el que causa el fallo. Aquí está el trocito que corresponde a la pila anterior obtenida con el GDB:


==23292== Invalid read of size 4
==23292== Invalid read of size 4
==23292==    at 0x806BD9E: TreeMapItem::parent() const (treemap.h:285)
==23292==    at 0x806BD9E: TreeMapItem::parent() const (treemap.h:285)
==23292==    by 0x8065FB9: TreeMapItemList::compareItems(void*, void*) (treemap.cpp:720)
==23292==    by 0x8065FB9: TreeMapItemList::compareItems(void*, void*) (treemap.cpp:720)
==23292==    by 0x50AC618: QGList::operator==(QGList const&) const (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==    by 0x50AC618: QGList::operator==(QGList const&) const (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==    by 0x806D3BF: QPtrList<TreeMapItem>::operator==(QPtrList<TreeMapItem> const&) const (qptrlist.h:74)
==23292==    by 0x806D3BF: QPtrList<TreeMapItem>::operator==(QPtrList<TreeMapItem> const&) const (qptrlist.h:74)
==23292==    by 0x8062DE7: TreeMapWidget::mousePressEvent(QMouseEvent*) (treemap.cpp:1840)
==23292==    by 0x8062DE7: TreeMapWidget::mousePressEvent(QMouseEvent*) (treemap.cpp:1840)
==23292==    by 0x4E2FA62: QWidget::event(QEvent*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==    by 0x4E2FA62: QWidget::event(QEvent*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==    by 0x4D96CA6: QApplication::internalNotify(QObject*, QEvent*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==    by 0x4D96CA6: QApplication::internalNotify(QObject*, QEvent*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==    by 0x4D97A87: QApplication::notify(QObject*, QEvent*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==    by 0x4D97A87: QApplication::notify(QObject*, QEvent*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==    by 0x4809AC3: KApplication::notify(QObject*, QEvent*) (kapplication.cpp:550)
==23292==    by 0x4809AC3: KApplication::notify(QObject*, QEvent*) (kapplication.cpp:550)
==23292==    by 0x4D36FD1: QETWidget::translateMouseEvent(_XEvent const*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==    by 0x4D36FD1: QETWidget::translateMouseEvent(_XEvent const*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==    by 0x4D368AF: QApplication::x11ProcessEvent(_XEvent*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==    by 0x4D368AF: QApplication::x11ProcessEvent(_XEvent*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==    by 0x4D46760: QEventLoop::processEvents(unsigned) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==    by 0x4D46760: QEventLoop::processEvents(unsigned) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==  Address 0x2C is not stack'd, malloc'd or (recently) free'd
==23292==  Address 0x2C is not stack'd, malloc'd or (recently) free'd


But to be sure, just attach the whole log file to the crash report.
Pero, para estar seguro, adjunte todo el fichero al informe de fallos.

Latest revision as of 08:31, 20 November 2008

Introducción

Este documento describe cómo crear pilas de las últimas funciones ejecutadas de un casque de una aplicación KDE. Primero se muestra algo de información general y luego se describe cómo preparar KDE en varias distribuciones para obtener estas pilas. Esto debería ser bastante para la mayoría de los casos. Hay secciones adicionales sobre cómo obtener la pila de las últimas funciones ejecutas con el depurador GNU (GDB) y con Valgrind, que son útiles en algunos casos.

Cómo crear informes de fallos útiles

Un buen informe de fallos en Bugzilla consiste de dos partes:

  • Una descripción de cómo reproducir el fallo, y
  • una pila de las últimas funciones ejecutadas (backtrace en inglés) en el momento del fallo.

Si falla uno de estos elementos, se vuelve mucho más dificil, si no imposible, resolver el problema a los desarrolladores.

Una descripción debería consistir en algo más que "cascó". Intente describir todo lo que estaba haciendo en el momento del fallo con el KDE, por ejemplo: ¿pulsó un botón, abrió una web o un fichero en particular que causó los problemas? Recuerde que el desarrollador intentará averiguar dónde está el fallo siguiendo los pasos descritos en el informe. Cualquier detalle que le pueda parecer superfluo relacionado con el fallo podría ser la clave para el desarrollador, así que escríbalo. Más vale pecar por exceso de información que por defecto.

Hay un artículo sobre cómo escribir buenos informes de fallos en este enlace, por favor, leálo antes de informar sobre fallos.

No adjunte la pila de las últimas funciones ejecutadas al informe, simplemente péguelo en el. De este modo es mucho más fácil buscar informes duplicados, porque no se busca en los ficheros adjuntos.

Al pegar la pila de las últimas funciones ejecutadas, elimine la mayoría de las líneas

(no debugging symbols found)

excepto una o dos de cada bloque, porque lo hacen más dificil de leer.

Aunque pegar la pila de las últimas funciones ejecutadas directamente al informe se prefiere a añadirlo como adjunto, por favor, no haga lo mismo con otra información como trazas (valgrind, strace o salida del terminal) o datos de ejemplo (correos, ficheros HTML,...), utilize ficheros adjuntos para esos datos.

pila de las últimas funciones ejecutadas

La pila de las últimas funciones ejecutadas, aunque pueda parecer un galimatías, contiene información muy valiosa para los desarrolladores. Estas pilas describen qué funciones se llamaron justo en el momento del fallo, así que los desarrolladores puede saber qué funciones son las culpables del fallo. Pero tener buenas pilas tiene un lado negativo, los ejecutables y bibliotecas que se utilizan ocupan mucho más espacio en disco que sus equivalentes optimizados. Por esta razón la mayoría de las distribuciones elijen instalar ejecutables sin símbolos de depuración (stripped en inglés), que producen pilas de últimas funciones ejecutadas inservibles:

(no debugging symbols found)
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
[Thread debugging using libthread_db enabled]
[New Thread -1233848624 (LWP 12212)]
[New Thread -1255081072 (LWP 12820)]
[New Thread -1240921200 (LWP 12819)]
[New Thread -1266680944 (LWP 12818)]
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
0xffffe410 in __kernel_vsyscall ()
#0  0xffffe410 in __kernel_vsyscall ()
#1  0xb6a1210b in ?? () from /lib/tls/i686/cmov/libpthread.so.0
#2  0xb6a85afe in ?? () from /usr/lib/libX11.so.6
#3  0x00000003 in ?? ()
#4  0x082149c0 in ?? ()
#5  0x00003ffc in ?? ()
#6  0x00000000 in ?? ()

Pero no todo está perdido, con algunas pequeñas modificaciones se pueden crear pilas de las últimas funciones ejecutadas con toda la información necesaria para los desarrolladores de KDE.

Preparando los paquetes KDE

Si su distribución tiene paquetes de depuración (debug), instálelos.

Es fácil saber qué paquetes depuración hacen falta mirando la pila de las últimas funciones ejecutadas. Por ejemplo, de una línea como la siguiente:

#6  0xb7975bdc in ?? () from /usr/lib/libkmailprivate.so.4

El ?? indica que la biblioteca libkmailprivat.so.4 no tiene información de depuración, que puede estar disponible en paquetes de depuración separados. En este caso, es bastante fácil averiguar que necesita instalar los paquetes de depuración de KMail para obtener una pila con información útil.

A veces, necesitará instalar más de un paquete de depuración para obtener una buena pila. Esto depende de cómo su distribución divida los paquetes. Por ejemplo, en algunas distribuciones es suficiente instalar el paquete de depuración para kdepim para obtener suficiente información para un casque en KMail, para otras distribuciones hay un paquete de depuración adicional para KMail.

Aquí hay una lista de cómo obtener paquetes de depuración para algunas distribuciones:

  • Debian - Debian ofrece paquetes -dbg para facilitar la tarea de crear pilas útiles. Al instalar el paquete de depuración correspondiente -dbg, por ejemplo kdepim-dbg para casques de KMail, las dependencias de los paquetes hacen que se instalen todos los paquetes necesarios y en el orden correcto (kdelibs-dbg, gdb, ...).
  • FreeBSD ports - Por favor, mire en KDE las preguntas más frecuentes de FreeBSD.
  • Gentoo - Gentoo tiene su propio documento (en inglés) describiendo cómo proceder.
  • Mandriva - Mandriva 2007.0 y posteriores tienen paquetes adicionales de depuración para todos sus paquetes (incluyendo KDE). Sólo hay que instalar el paquete correspondiente -debug, como kdebase-debug y kdemultimedia-debug. También debería instalar kdelibs-debug.
    • Note: Los paquetes -debug están en repositorios separados. Por ejemplo, para todos los paquetes en main, encontrará los paquetes de depuración en el repositorio debug_main.
  • Kubuntu/Ubuntu - Las distribuciones Ubuntu hacen estas cosas fáciles. Cada paquete oficial KDE tiene un paquete adicional en el repositorio, con el sufijo -dbg. Siempre hay que instalar kdelibs5-dbg, porque todas las aplicaciones KDE utilizan kdelibs (kdelibs-dbg para las aplicaciones KDE 3). Luego debería instalar el paquete -dbg para la aplicación que falló. Por ejemplo, si falló KOrganizer, debería instalar kdepim-dbg. Si el programa no es un módulo oficial KDE y no tiene paquete -dgb, puede instalar el paquete -dbgsym desde el repositorio listado en su página Debugging Program Crashes.
  • openSUSE - Sólo hay que instlar los paquetes -debuginfo, por ejemplo: kdepimlibs4-debuginfo. Se pueden encontrar estos paquetes en los repositorios KDE. También tiene una página dedicada a la depuración.
  • Fedora - Fedora has its own document describing how to proceed. (A debuginfo repository has to be enabled.)

Si su distribución no incluye paquetes de depuración para KDE, tendría que compilar KDE desde el código fuente:

  • Si está usando KDE3, entonces en la etapa de configuración, debería añadir el parámetro --enable-debug=full para obtener símbolos de depuración en los ficheros resultantes.
  • Si está usando KDE4, entonces en la etapa cmake, debe añadir el parámetro -DCMAKE_BUILD_TYPE=debugfull. Si quiere especificar sus propios CXXFLAGS, entonces utilize -DCMAKE_BUILD_TYPE=None CMAKE_CXX_FLAGS="-O0 -g". Puede cambiar los CMAKE_CXX_FLAGS para que se ajuste a sus necesidades.

Luego son los conocidos make y make install habituales.

Crash!

Ahora, a hacer fallar la aplicación de nuevo (una buena forma de tener una excelente descripción de cómo reproducir el fallo). El diálogo de aplicación fallida debería aparecer después del fallo, mostrando la pila de últimas funciones ejecutadas.


KDE Crash Dialog
KDE Crash Dialog

Pulse en la pestaña Backtrace y espere un buen rato, el proceso puede ocupar muchar memoria y mucho procesador, así que el resto de procesos pueden ralentizarse mucho. Pero el resultado debe ser ahora muchísimo mejor, por ejemplo:

Using host libthread_db library "/lib/libthread_db.so.1". 
[Thread debugging using libthread_db enabled] 
[New Thread -1232783168 (LWP 7604)] 
[KCrash handler] 
#6  0x0806be76 in TreeMapItem::parent (this=0x0) 
    at /home/bram/KDE/kde3/kdeaddons/konq-plugins/fsview/treemap.h:285 
#7  0x08065fea in TreeMapItemList::compareItems (this=0xbfec04a8, item1=0x0, 
    item2=0x0) 
    at /home/bram/KDE/kde3/kdeaddons/konq-plugins/fsview/treemap.cpp:720 
#8  0xb7281619 in QGList::operator== () from /usr/qt/3/lib/libqt-mt.so.3 
#9  0x0806d498 in QPtrList<TreeMapItem>::operator== (this=0xbfec04a8, 
    list=@0xbfec0468) at /usr/qt/3/include/qptrlist.h:74 
#10 0x08062e18 in TreeMapWidget::mousePressEvent (this=0xbfec03ac, 
    e=0xbfebff1c) 
    at /home/bram/KDE/kde3/kdeaddons/konq-plugins/fsview/treemap.cpp:1840 
#11 0xb7004a63 in QWidget::event () from /usr/qt/3/lib/libqt-mt.so.3 
#12 0xb6f6bca7 in QApplication::internalNotify () 
   from /usr/qt/3/lib/libqt-mt.so.3 
#13 0xb6f6ca88 in QApplication::notify () from /usr/qt/3/lib/libqt-mt.so.3 
#14 0xb7725a84 in KApplication::notify (this=0xbfec055c, receiver=0xbfec03ac, 
    event=0xbfebff1c) 
    at /home/bram/KDE/kde3/kdelibs/kdecore/kapplication.cpp:550 
#15 0xb6f0bfd2 in QETWidget::translateMouseEvent () 
   from /usr/qt/3/lib/libqt-mt.so.3 
#16 0xb6f0b8b0 in QApplication::x11ProcessEvent () 
   from /usr/qt/3/lib/libqt-mt.so.3 
#17 0xb6f1b761 in QEventLoop::processEvents () from /usr/qt/3/lib/libqt-mt.so.3 
#18 0xb6f82831 in QEventLoop::enterLoop () from /usr/qt/3/lib/libqt-mt.so.3 
#19 0xb6f826b6 in QEventLoop::exec () from /usr/qt/3/lib/libqt-mt.so.3 
#20 0xb6f6b72f in QApplication::exec () from /usr/qt/3/lib/libqt-mt.so.3 
#21 0x0805181e in main (argc=134673960, argv=0xffffffff) 
    at /home/bram/KDE/kde3/kdeaddons/konq-plugins/fsview/main.cpp:55

Parece mucho mejor, ¿verdad? Muestra a los desarrolladores las direcciones de memoria, los ficheros fuente y los números de línea, además de los parámetros pasados a las funciones. Así es mucho más facil resolver el fallo.

Note
Se necesita tener instalado GDB para obtener las pilas de las últimas funciones ejecutadas en un fallo. Mire la siguiente sección para saber qué es GDB y como instalarlo.


Obteniendo la pila de las últimas funciones ejecutadas con GDB

En algunos casos, no es posible crear la pila de las últimas funciones ejecutadas dentro del diálogo de aplicación fallida del KDE. Esto puede ser porque una aplicacón entró en un bucle sin fin, o el diálogo de aplicación fallida no aparece por algún motivo. Siempre puede intentar obtener la instantánea de donde aparece el fallo con gdb, el depurador GNU . GDB está disponible para instalarse en la inmensa mayoría de las distribuciones en su almacén de programas.

Hay dos formas de utilizar GDB:

  • iniciar una aplicación dentro de gdb, o
  • depurar una aplicación que ya está funcionando, útil en el caso de una aplicación que se encuentra en un bucle sin fin.

Primero empezaremos por iniciar una aplicación dentro de gdb. Desde el terminal, ejecutamos:

$ gdb someKDEapp

La línea de comandos del GDB aparecerá. Todavía no se ha iniciado la aplicación, para ello hay que invocar el comando run:

(gdb) run

Esto iniciará la aplicación como de costumbre, y se puede trabajar con ella de forma normal (sólo consume mucha más memoria que de costumbre y puede ir un poco más lenta de lo normal). Ahora, a reproducir el fallo. Cuando se tenga éxito, la aplicación se cerrará y debería estar en la línea de comandos del GDB. Ahora a mostrar la pila (backtrace en inglés):

Note
Algunas aplicaciones KDE (como JuK y KTorrent) sólo permiten iniciar la aplicación una vez. Para estos casos, habría que escribir "run --nofork" en la línea de comandos del gdb en lugar de "run", o gdb intentará depurar el proceso incorrecto. Si no está seguro de cuándo debe utlizar --nofork, simplemente úselo. Si la aplicación dice que es una opción desconocida, entondes debe quitar el --nofork.


(gdb) thread apply all backtrace

Esto debería dar una pila de las últimas funciones ejecutadas que puede ser pegado en el Bugzilla de KDE.

En el caso de depurar una aplicación ya iniciada, ejecute el siguiente comando en el terminal:

$ gdb la_aplicación_KDE pid

donde pid es el IDentificador del proceso que se quiere depurar. Una vez que se ha enganchado, si el proceso está en bucle sin fin, después de utilizar el comando gdb 'backtrace' aparecerá una pila de las últimas funciones ejecutadas util. Después se puede utilizar el comando gdb 'continue' para dejar que la aplicación siga ejecutándose y pulsando Ctrl+C en gdb permitirá de nuevo introducir comandos.

Obteniendo la pila de las últimas funciones ejecutadas con Valgrind

Cuando se trata de fallos, Valgrind es también una herramienta muy útil para crear pilas de las últimas funciones ejecutadas. No es un sustituto del GDB, sino un suplemento.

Cuando se inicia una apliación en valgrind, cada operación de memoria del proceso se comprueba. Valgrind generará un informe de operaciones de memoria incorrectas del proceso por la salida estándard o en fichero de trazas. Como la mayoría de los fallos se deben a la lectura de la memoria del proceso incorrecta, valgrind es muy útil para rastrear dónde ocurre el fallo.

Note
Valgrind contiene varias herramientas para probar o perfilar una aplicación. Para este artículo, sólo utilizamos memcheck, la herramienta por defecto cuando valgrind se invoca.


Como GDB, Valgrind utiliza mucha más memoria y hace que la aplicación funcione mucho más despacio.

Para iniciar la aplicación con valgrind:

$ valgrind --log-file=la_aplicación_KDE_a_depurar la_aplicación_KDE_a_depurar

Ahora, el reproducir el fallo, la aplicación y valgrind acabarán. Lo que queda es un fichero llamado la_aplicación_KDE_a_depurar.pid donde pid se sustituye por el ID del proceso de valgrind. Este fichero puede contener más errores que el que causa el fallo. Aquí está el trocito que corresponde a la pila anterior obtenida con el GDB:

==23292== Invalid read of size 4
==23292==    at 0x806BD9E: TreeMapItem::parent() const (treemap.h:285)
==23292==    by 0x8065FB9: TreeMapItemList::compareItems(void*, void*) (treemap.cpp:720)
==23292==    by 0x50AC618: QGList::operator==(QGList const&) const (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==    by 0x806D3BF: QPtrList<TreeMapItem>::operator==(QPtrList<TreeMapItem> const&) const (qptrlist.h:74)
==23292==    by 0x8062DE7: TreeMapWidget::mousePressEvent(QMouseEvent*) (treemap.cpp:1840)
==23292==    by 0x4E2FA62: QWidget::event(QEvent*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==    by 0x4D96CA6: QApplication::internalNotify(QObject*, QEvent*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==    by 0x4D97A87: QApplication::notify(QObject*, QEvent*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==    by 0x4809AC3: KApplication::notify(QObject*, QEvent*) (kapplication.cpp:550)
==23292==    by 0x4D36FD1: QETWidget::translateMouseEvent(_XEvent const*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==    by 0x4D368AF: QApplication::x11ProcessEvent(_XEvent*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==    by 0x4D46760: QEventLoop::processEvents(unsigned) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)
==23292==  Address 0x2C is not stack'd, malloc'd or (recently) free'd

Pero, para estar seguro, adjunte todo el fichero al informe de fallos.