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

From KDE TechBase
(Sezione backtrace tradotta.)
No edit summary
 
(10 intermediate revisions by one other user not shown)
Line 1: Line 1:
{{Template:I18n/Language Navigation Bar|Development/Tutorials/Debugging/How to create useful crash reports}}
 


== Introduzione ==
== Introduzione ==


Questo documento descrive come riprodurre un backtrace (ovvero una "traccia dell'esecuzione") di applicazioni KDE che vanno in crash. Inizialmente vengono fornite alcune informazioni generali; nel seguito vengono descritte le procedure per ottenere i pacchetti KDE per varie distribuzioni utili a ottenere i backtrace. Queste parti dovrebbero essere sufficienti per la maggior parte della gente. Ci sono alcune sezioni addizionali su come creare backtrace con il GNU Debugger e con Valgrind, che possono essere utili in alcuni casi.  
Questo documento descrive come riprodurre un backtrace (ovvero una "traccia dell'esecuzione") di applicazioni KDE che vanno in crash. Inizialmente vengono fornite alcune informazioni generali; nel seguito vengono descritte le procedure per ottenere i pacchetti KDE per varie distribuzioni utili a ottenere i backtrace. Queste parti dovrebbero essere sufficienti per la maggior parte dei casi. Ci sono alcune sezioni addizionali su come creare backtrace con il GNU Debugger e con Valgrind, che possono essere utili in alcuni casi.  


== Come creare segnalazioni di crash utili ==
== Come creare segnalazioni di crash utili ==
Line 25: Line 25:
=== Backtrace ===
=== Backtrace ===


I backtrace sono essenziali. Possono sembrare senza significato per i non addetti, ma in realtà possono contenere una gran quantità di informazioni utili. Un backtrace descrive quali funzioni sono state chiamate prima del crash, in modo che gli sviluppatori possano tracciare in quale metodo è partito il problema. Ottenere buoni backtrace ha uno svantaggio: [[Development/Tutorials/Debugging/Debugging_symbols|le librerie e gli eseguibili occupano molto più spazio rispetto alla versione ottimizzata]]. È per questo motivo che molte distribuzioni scelgono di intallare file senza simboli di debugging, '''che causa la creazione di backtrace inutili":
I backtrace sono essenziali. Possono sembrare senza significato per i non addetti, ma in realtà possono contenere una gran quantità di informazioni utili. Un backtrace descrive quali funzioni sono state chiamate prima del crash, in modo che gli sviluppatori possano tracciare in quale metodo è partito il problema. Ottenere buoni backtrace ha uno svantaggio: [[Development/Tutorials/Debugging/Debugging_symbols|le librerie e gli eseguibili occupano molto più spazio rispetto alla versione ottimizzata]]. È per questo motivo che molte distribuzioni scelgono di installare file senza simboli di debugging, '''cosa che causa la creazione di backtrace inutili''' come questo:


  (no debugging symbols found)
  (no debugging symbols found)
Line 61: Line 61:
Per fortuna non c'è da preoccuparsi, con alcune modifiche è possibile creare backtrace con tutte le informazioni necessarie per le applicazioni KDE.
Per fortuna non c'è da preoccuparsi, con alcune modifiche è possibile creare backtrace con tutte le informazioni necessarie per le applicazioni KDE.


===Preparing your KDE packages===
=== Preparare i pacchetti KDE ===


If your distribution has debugging-enabled packages, install them.
Se la distribuzione in uso ha pacchetti predisposti per il debugging è necessario installarli.


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:
È facile vedere quali pacchetti di debug manchino guardando il backtrace. Prendiamo in considerazione la seguente linea di una backtrace:


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


The <tt>??</tt> indicates that the library <tt>libkmailprivate.so.4</tt> 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.
Il simbolo <tt>??</tt> indica che la libreria <tt>libkmailprivate.so.4</tt> è priva di informazioni di debug, che potrebbero essere disponibili in pacchetti di debug separati. In questo caso, è facile capire che è necessario installare i pacchetti di debug per KMail per ottenere un backtrace migliore.


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 <tt>kdepim</tt> to get enough debugging information for a crash in KMail, for other distributions there is an additional debug package just for KMail.
Alcune volte, c'è bisogno di installare più di un pacchetto di debug per ottenere un buon backtrace. Ciò dipende da come le distribuzioni suddividono i pacchetti. Per esempio, per alcune distribuzioni è sufficiente installare il pacchetto per <tt>kdepim</tt> per avere sufficienti informazioni riguardo un crash in KMail, in altre distribuzioni c'è un pacchetto di debug aggiuntivo per KMail.


Here's a list of how to obtain debug packages for some distributions:
Qui ci sono le istruzioni che spiegano come ottenere i pacchetti di debug per alcune distribuzioni:


*'''Debian''' - Debian offers <tt>-dbg</tt> packages to easy create useful backtraces. Just install the corresponding <tt>-dbg</tt> package. e.g. <tt>kdepim-dbg</tt> for KMail crashes. The dependencies of -dbg makes sure to pull in the other right packages (kdelibs-dbg, gdb, and so on).
*'''Debian''' - Debian offre pacchetti <tt>-dbg</tt> per creare facilmente backtrace utili. Basta installare il corrispondente pacchetto <tt>-dbg</tt>. ad esempio <tt>kdepim-dbg</tt> per i crash di KMail. Le dipendenze di -dbg assicurano di ottenere anche gli altri pacchetti necessari (kdelibs-dbg, gdb, e così via).
<!--*'''Fedora''' ???-->
*'''FreeBSD ports''' - Fare riferimento alla pagina [http://freebsd.kde.org/faq.php#AKDEapplicationcrashedandIwanttofileabugreportathttpbugskdeorgbutthebacktraceintheKDECrashManagerisuselessWhatcanIdo delle FAQ di KDE su FreeBSD].
*'''FreeBSD ports''' - Please refer to the [http://freebsd.kde.org/faq.php#AKDEapplicationcrashedandIwanttofileabugreportathttpbugskdeorgbutthebacktraceintheKDECrashManagerisuselessWhatcanIdo KDE on FreeBSD FAQ].
*'''Gentoo''' - Gentoo ha [http://www.gentoo.org/proj/en/qa/backtraces.xml una guida] che descrive come procedere.
*'''Gentoo''' - Gentoo has its [http://www.gentoo.org/proj/en/qa/backtraces.xml own document] describing how to proceed.
*'''Mandriva''' - A partire da Mandriva 2007.0 in su ci sono pacchetti addizionali per tutto KDE. È sufficiente installare il corrispondente pacchetto <tt>-debug</tt>, come <tt>kdebase-debug</tt> e <tt>kdemultimedia-debug</tt>. Quasi certamente va installato <tt>kdelibs-debug</tt> in ogni caso.
*'''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 <tt>-debug</tt> package, like <tt>kdebase-debug</tt> and <tt>kdemultimedia-debug</tt>. You probably want to install <tt>kdelibs-debug</tt> anyways.
** Nota: i pacchetti <tt>-debug</tt> sono in repository separati. Ad esempio, per tutti i pacchetti in <tt>main</tt>, si possono trovare i pacchetti di debug nel  repository <tt>debug_main</tt>.
** Note: the <tt>-debug</tt> packages are in separate repositories. For instance, for all packages in <tt>main</tt>, you'll find the debugging package in repository <tt>debug_main</tt>.
*'''Kubuntu/Ubuntu''' - La famiglia di distribuzioni Ubuntu rende le cose abbastanza facili. Ogni modulo ufficiale di KDE ha un pacchetto aggiuntivo nei repository con il suffisso <tt>-dbg</tt>. È importante installare sempre  <tt>kdelibs5-dbg</tt>, in quanto tutte le applicazioni KDE usano kdelibs (kdelibs-dbg per applicazioni KDE 3). Oltre a ciò è necessario installare il pacchetto -dbg anche per l'applicazione che è andata in crash. Per esempio se si è piantato KOrganizer è necessario installare anche <tt>kdepim-dbg</tt>. Se il programma non fa parte di un modulo ufficiale di KDE e non ha un apposito pacchetto -dbg, è possibile installare il pacchetto -dbgsym dal repository in questa [https://wiki.kubuntu.org/DebuggingProgramCrash pagina sul debugging dei programmi].   
*'''Kubuntu/Ubuntu''' - The Ubuntu family makes things quite easy. Every official KDE module has an additional package in the repository, suffixed with <tt>-dbg</tt>. Always install <tt>kdelibs5-dbg</tt>, 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 <tt>kdepim-dbg</tt> 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 [https://wiki.kubuntu.org/DebuggingProgramCrash Debugging Program Crashes] page.   
** Durante il ciclo di sviluppo di Ubuntu il gestore di crash Apport è attivo e si preoccuperà di riportare i crash a launchpad.net e creare il backtrace per te. Se si desidera utilizzare il gestore dei crash di KDE è possibile disabilitarlo nel file /etc/defaults/apport
*:During the Ubuntu development cycle the Apport crash handler is turned on which will report crashes to launchpad.net and do the backtrace for you, if you would rather use the KDE crash handler turn Apport off in /etc/defaults/apport
** A partire da Lucid Lynx (10.04) Kubuntu inoltrerà tutti i bug che non sono peculiari della distribuzione al sistema di gestione di KDE; Apport è ora disabilitato in modo da utilizzare DrKonqui come gestore predefinito dei crash.
*:Starting with Lucid Lynx (10.04) Kubuntu will be forwarding all non kubuntu specific bugs upstream and had disabled Apport so that DrKonqui will be th edefault crash handler.
*'''openSUSE''' - È necessario solo installare i pacchetti <tt>-debuginfo</tt>, ad esempio: <tt>kdepimlibs4-debuginfo</tt>. È possibile trovare questi pacchetti nei [http://en.opensuse.org/KDE/Repositories repository KDE]. C'è anche una [http://en.opensuse.org/Bugs:An_application_crashed pagina dedicata al debugging in openSUSE].
*'''openSUSE''' - You should only install the <tt>-debuginfo</tt> packages, for example: <tt>kdepimlibs4-debuginfo</tt>. You can find these packages in [http://en.opensuse.org/KDE/Repositories KDE repositories]. There is also a dedicated [http://en.opensuse.org/Bugs:An_application_crashed openSUSE debugging page].
*'''Fedora''' - In Fedora è sufficiente utilizzare i seguenti comandi:
*'''Fedora''' - Fedora has its [http://fedoraproject.org/wiki/StackTraces own document] describing how to proceed. (A debuginfo repository has to be enabled.)
*# <tt>yum provides "/usr/lib/libkmailprivate.so.4"</tt> per trovare quale pacchetto fornisce quel file;
*# <tt>debuginfo-install kdepim</tt> da utente root per installare i pacchetti di debug per quel pacchetto (dipendenze incluse).
*: Una guida completa e dettagliata per Fedora è disponibile in [http://fedoraproject.org/wiki/StackTraces questo documento] che descrive come procedere. Fedora utilizza un repository debuginfo separato che va abilitato. Si consiglia anche di utilizzare il plugin yum <tt>auto-update-debug-info</tt> per tenere aggiornati i pacchetti debuginfo.


If your distribution doesn't have debugging-enabled packages for KDE, you'll have to compile KDE from sources:
Nel raro caso in cui la distribuzione non abbia pacchetti contenenti i simboli di debug per KDE, è necessario compilare KDE dai sorgenti:


* If you're using KDE 3, then at the configure stage, you should supply the parameter <tt>--enable-debug=full</tt> in order to build debug symbols in the resulting files.
* Nel caso di KDE 3, al passo di configure, è necessario passare il parametro <tt>--enable-debug=full</tt> al fine di creare i simboli di debug nei file risultanti.
* If you're using KDE 4, then at the cmake stage, you should supply the parameter <tt>-DCMAKE_BUILD_TYPE=debugfull</tt>. If you want to specify your own CXXFLAGS, then use <tt>-DCMAKE_BUILD_TYPE=None CMAKE_CXX_FLAGS="-O0 -g"</tt>.  You can change the CMAKE_CXX_FLAGS as appropriate for your needs.
* Nel caso di KDE 4, al passo di cmake, è necessario passare il parametro <tt>-DCMAKE_BUILD_TYPE=debugfull</tt>. Se si vuole passare opzioni personalizzate a CXXFLAGS, utilizzare <tt>-DCMAKE_BUILD_TYPE=None CMAKE_CXX_FLAGS="-O0 -g"</tt>.  È possibile cambiare le opzioni CMAKE_CXX_FLAGS in base alle proprie necessità.


Then it's just <tt>make</tt> and <tt>make install</tt> as you're used to.
Dopodiché è sufficiente dare <tt>make</tt> e <tt>make install</tt> come al solito.


===Crash!===
===Crash!===


Now it's time to crash your application. The KDE Crash Dialog should appear right after the crash, which shows the Backtrace tab.
Ora che sono state reperite le informazioni per rendere utile la traccia dell'esecuzione va riprodotto il crash nell'applicazione. La finestra di dialogo di KDE apparirà qualche istante dopo al crash dell'applicazione.


[[Image:Kde-crash-handler.png|center|300px|KDE Crash Dialog]]
[[Image:Kde-crash-handler.png|center|300px|La finestra di dialogo dei crash di KDE]]


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:
Ora la generazione del backtrace dovrebbe risultare molto più completa, ad esempio:


  Using host libthread_db library "/lib/libthread_db.so.1".  
  Using host libthread_db library "/lib/libthread_db.so.1".  
Line 135: Line 137:
     at /home/bram/KDE/kde3/kdeaddons/konq-plugins/fsview/main.cpp:55
     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.
Molto meglio, vero? In questo backtrace sono presenti gli indirizzi di memoria, i file sorgenti, i numeri di riga e i parametri passati alle funzioni che hanno causato il problema. Ciò rende più facile per gli sviluppatori capire la causa del problema, in quanto sanno dove guardare.


{{note|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.}}
{{note|È '''obbligatorio''' avere GDB installato per ottenere il backtrace di un crash. Nella sezione seguente è spiegato cos'è GDB e come installarlo.}}


===Retrieving a backtrace with GDB===
===Ottenere un backtrace con GDB===


In some cases, it is not possible to create a backtrace with the KDE Crash Dialog. This may be caused by an application which entered an infinite loop, or the crash dialog did not appear at all for some reason. You can try to grab a backtrace with <tt>gdb</tt>, the [http://sourceware.org/gdb/ GNU Debugger]. GDB is widely available through distribution packages.
In alcuni casi non è possibile creare un backtrace con la finestra di dialogo dei crash di KDE. Ciò può essere dovuto da un'applicazione entrata in un loop infinito, o dal fatto che la finestra del crash non è apparsa per qualche motivo. In tali casi è possibile ottenere un backtrace con <tt>gdb</tt>, il [http://sourceware.org/gdb/ Debugger GNU]. GDB è disponibile pacchettizzato per tutte le distribuzioni più importanti.


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:
Il richiamo di GDB dipende dalle situazioni. È possibile sia eseguire un'applicazione all'interno di gdb che collegare gdb ad un processo già in esecuzione. Quest'ultima situazione in particolare è utile quando un'applicazione è già entrata in un loop infinito. Cominciamo con la prima soluzione; per eseguire un'applicazione da gdb digitare sulla riga di comando:


  $ gdb someKDEapp
  $ gdb someKDEapp


The GDB prompt will appear. Note that this does not start the application itself, you should run it by invoking the <tt>run</tt> command:
Apparirà il prompt di GDB. Per avviare l'applicazione, al momento non ancora avviata, è necessario invocare il comando<tt>run</tt>:


  (gdb) run
  (gdb) 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:
{{note|Alcune applicazioni di KDE (ad esempio JuK e KTorrent) contengono del codice speciale per assicurarsi che ci sia una sola istanza dell'applicazione avviata alla volta. Per queste applicazioni bisogna utilizzare il comando "run --nofork" al prompt di (gdb) invece di "run" perché altrimenti gdb proverebbe a debuggare il processo sbagliato. In caso di dubbio su quale usare è sufficiente provare ad avviare l'applicazione con l'opzione --nofork: se l'applicazione dice che è un'opzione sconosciuta è possibile rimuovere l'opzione --nofork.}}


{{note|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.}}
Questo avvierà l'applicazione a cui siete abituati, e vi permetterà di lavorarci come fate solitamente (con la differenza che consumerà molta più memoria e potrebbe risultare molto più lenta). Ora va riprodotto il crash. Quando l'applicazione va in crash essa si chiuderà riportando al prompt di GDB. Ora è necessario invocare il comando 'backtrace':


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


This should give a good backtrace which can be posted at the KDE Bugzilla.
Ciò dovrebbe fornire una buona backtrace che può essere inserita nel Bugzilla di KDE.


In case you want to attach to an existing process, run the following command in the shell:
In caso si voglia collegarsi ad un processo già esistente va invocato il seguente comando:


  $ gdb someKDEapp pid
  $ gdb someKDEapp pid


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.
dove ''pid'' è il process ID del processo al quale ci si vuole collegare. Una volta collegati, quando il processo è in un ciclo infinito, dopo aver usato il comando 'backtrace' apparirà una traccia dell'esecuzione. È possibile utilizzare il comando 'continue' per lasciare l'applicazione eseguire nuovamente e premere Ctrl+C in gdb per poter inserire nuovamente dei comandi.


===Retrieving a backtrace with Valgrind===
===Ottenere un backtrace con Valgrind===


When it comes to crashes, [http://www.valgrind.org Valgrind] is also a useful tool to create a backtrace. It's not a substitution for GDB, but rather a supplement.
Un altro strumento utile per creare backtrace di crash è [http://www.valgrind.org Valgrind]; esso non sostituisce GDB, ma piuttosto lo completa.


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.
Quando si esegue un'applicazione in valgrind ogni pezzo di memoria letta o scritta dall'applicazione stessa viene controllato. Valgrind riporterà operazioni non valide in memoria nello standard output o in un file di log. Dato che la maggior parte dei crash sono dovuti a letture invalide in memoria, Valgrind può essere utile per tracciare dove succedono i problemi.


{{note|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 consiste di vari tool per verificare o effettuare la profilazione di un'applicazione. In questo articolo useremo solo memcheck, il tool di default che viene chiamato all'esecuzione di valgrind.}}


Like GDB, Valgrind makes running an application much slower, while consuming a lot more resources.
Come GDB, Valgrind rende l'esecuzione delle applicazioni molto più lento e più esoso in termini di risorse.


Start the application within valgrind:
Per avviare l'applicazione all'interno di valgrind:


  $ valgrind --log-file=someKDEapp someKDEapp
  $ valgrind --log-file=someKDEapp someKDEapp


Now reproduce the crash. As soon as this happens, the application and valgrind will terminate. What's left is a file named <tt>someKDEapp.pid</tt> 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:
Ora va riprodotto il crash. Appena avviene sia l'applicazione che valgrind termineranno. Ciò che rimane è un file con nome <tt>someKDEapp.pid</tt> dove ''pid'' sarà il process ID del processo valgrind. Il file potrebbe elencare più errori di quanti siano effettivamente causa del crash. Qui c'è un esempio della parte che causa il crash che corrisponde al backtrace GDB sopra:


  ==23292== Invalid read of size 4
  ==23292== Invalid read of size 4
Line 196: Line 198:
  ==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.
Per essere sicuro allega alla segnalazione del bug l'intero file log fornito da valgrind.

Latest revision as of 12:27, 18 July 2012


Introduzione

Questo documento descrive come riprodurre un backtrace (ovvero una "traccia dell'esecuzione") di applicazioni KDE che vanno in crash. Inizialmente vengono fornite alcune informazioni generali; nel seguito vengono descritte le procedure per ottenere i pacchetti KDE per varie distribuzioni utili a ottenere i backtrace. Queste parti dovrebbero essere sufficienti per la maggior parte dei casi. Ci sono alcune sezioni addizionali su come creare backtrace con il GNU Debugger e con Valgrind, che possono essere utili in alcuni casi.

Come creare segnalazioni di crash utili

Una buona segnalazione di bug nel Bugzilla consiste di due parti: una descrizione di come riprodurre il crash ed un backtrace del crash stesso. Se manca uno di questi elementi risulta molto più difficile, se non impossibile, per gli sviluppatori affrontare il problema.

Una descrizione deve consistere di qualcosa più di un solo "si è piantato". È necessario cercare di descrivere qualsiasi cosa venga fatta prima del crash. È stato cliccato su un pulsante, aperto un particolare sito o file che ha causato il problema? Quel piccolo dettaglio che potrebbe sembrare inutile all'utente potrebbe risultare utile allo sviluppatore, quindi è sempre il caso di annotarlo nella segnalazione.

Un articolo approfondito su come scrivere delle buone descrizioni di bug e segnalazioni è disponibile a questo indirizzo, è caldamente consigliato leggerlo prima di effettuare delle segnalazioni.

Il backtrace di un crash non va allegato alla segnalazione; va semplicemente incollato in coda al testo della segnalazione stessa. In questo modo è molto più semplice per gli sviluppatori individuare segnalazioni duplicate dello stesso bug, in quanto la ricerca non avviene anche sul testo degli allegati.

Se si incolla un backtrace in una segnalazione assicurarsi di rimuovere tutte le righe, eccetto un paio, del tipo:

(no debugging symbols found)

dal backtrace, in quanto lo rendono più difficile da leggere.

Sebbene incollare backtrace direttamente sia preferibile rispetto ad aggiungere un allegato, non vanno incollate altre cose come log (valgrind, strace o output del terminale) o esempi di dati (email, file HTML e così via); per queste cose vanno usati gli allegati.

Backtrace

I backtrace sono essenziali. Possono sembrare senza significato per i non addetti, ma in realtà possono contenere una gran quantità di informazioni utili. Un backtrace descrive quali funzioni sono state chiamate prima del crash, in modo che gli sviluppatori possano tracciare in quale metodo è partito il problema. Ottenere buoni backtrace ha uno svantaggio: le librerie e gli eseguibili occupano molto più spazio rispetto alla versione ottimizzata. È per questo motivo che molte distribuzioni scelgono di installare file senza simboli di debugging, cosa che causa la creazione di backtrace inutili come questo:

(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 ?? ()

Per fortuna non c'è da preoccuparsi, con alcune modifiche è possibile creare backtrace con tutte le informazioni necessarie per le applicazioni KDE.

Preparare i pacchetti KDE

Se la distribuzione in uso ha pacchetti predisposti per il debugging è necessario installarli.

È facile vedere quali pacchetti di debug manchino guardando il backtrace. Prendiamo in considerazione la seguente linea di una backtrace:

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

Il simbolo ?? indica che la libreria libkmailprivate.so.4 è priva di informazioni di debug, che potrebbero essere disponibili in pacchetti di debug separati. In questo caso, è facile capire che è necessario installare i pacchetti di debug per KMail per ottenere un backtrace migliore.

Alcune volte, c'è bisogno di installare più di un pacchetto di debug per ottenere un buon backtrace. Ciò dipende da come le distribuzioni suddividono i pacchetti. Per esempio, per alcune distribuzioni è sufficiente installare il pacchetto per kdepim per avere sufficienti informazioni riguardo un crash in KMail, in altre distribuzioni c'è un pacchetto di debug aggiuntivo per KMail.

Qui ci sono le istruzioni che spiegano come ottenere i pacchetti di debug per alcune distribuzioni:

  • Debian - Debian offre pacchetti -dbg per creare facilmente backtrace utili. Basta installare il corrispondente pacchetto -dbg. ad esempio kdepim-dbg per i crash di KMail. Le dipendenze di -dbg assicurano di ottenere anche gli altri pacchetti necessari (kdelibs-dbg, gdb, e così via).
  • FreeBSD ports - Fare riferimento alla pagina delle FAQ di KDE su FreeBSD.
  • Gentoo - Gentoo ha una guida che descrive come procedere.
  • Mandriva - A partire da Mandriva 2007.0 in su ci sono pacchetti addizionali per tutto KDE. È sufficiente installare il corrispondente pacchetto -debug, come kdebase-debug e kdemultimedia-debug. Quasi certamente va installato kdelibs-debug in ogni caso.
    • Nota: i pacchetti -debug sono in repository separati. Ad esempio, per tutti i pacchetti in main, si possono trovare i pacchetti di debug nel repository debug_main.
  • Kubuntu/Ubuntu - La famiglia di distribuzioni Ubuntu rende le cose abbastanza facili. Ogni modulo ufficiale di KDE ha un pacchetto aggiuntivo nei repository con il suffisso -dbg. È importante installare sempre kdelibs5-dbg, in quanto tutte le applicazioni KDE usano kdelibs (kdelibs-dbg per applicazioni KDE 3). Oltre a ciò è necessario installare il pacchetto -dbg anche per l'applicazione che è andata in crash. Per esempio se si è piantato KOrganizer è necessario installare anche kdepim-dbg. Se il programma non fa parte di un modulo ufficiale di KDE e non ha un apposito pacchetto -dbg, è possibile installare il pacchetto -dbgsym dal repository in questa pagina sul debugging dei programmi.
    • Durante il ciclo di sviluppo di Ubuntu il gestore di crash Apport è attivo e si preoccuperà di riportare i crash a launchpad.net e creare il backtrace per te. Se si desidera utilizzare il gestore dei crash di KDE è possibile disabilitarlo nel file /etc/defaults/apport
    • A partire da Lucid Lynx (10.04) Kubuntu inoltrerà tutti i bug che non sono peculiari della distribuzione al sistema di gestione di KDE; Apport è ora disabilitato in modo da utilizzare DrKonqui come gestore predefinito dei crash.
  • openSUSE - È necessario solo installare i pacchetti -debuginfo, ad esempio: kdepimlibs4-debuginfo. È possibile trovare questi pacchetti nei repository KDE. C'è anche una pagina dedicata al debugging in openSUSE.
  • Fedora - In Fedora è sufficiente utilizzare i seguenti comandi:
    1. yum provides "/usr/lib/libkmailprivate.so.4" per trovare quale pacchetto fornisce quel file;
    2. debuginfo-install kdepim da utente root per installare i pacchetti di debug per quel pacchetto (dipendenze incluse).
    Una guida completa e dettagliata per Fedora è disponibile in questo documento che descrive come procedere. Fedora utilizza un repository debuginfo separato che va abilitato. Si consiglia anche di utilizzare il plugin yum auto-update-debug-info per tenere aggiornati i pacchetti debuginfo.

Nel raro caso in cui la distribuzione non abbia pacchetti contenenti i simboli di debug per KDE, è necessario compilare KDE dai sorgenti:

  • Nel caso di KDE 3, al passo di configure, è necessario passare il parametro --enable-debug=full al fine di creare i simboli di debug nei file risultanti.
  • Nel caso di KDE 4, al passo di cmake, è necessario passare il parametro -DCMAKE_BUILD_TYPE=debugfull. Se si vuole passare opzioni personalizzate a CXXFLAGS, utilizzare -DCMAKE_BUILD_TYPE=None CMAKE_CXX_FLAGS="-O0 -g". È possibile cambiare le opzioni CMAKE_CXX_FLAGS in base alle proprie necessità.

Dopodiché è sufficiente dare make e make install come al solito.

Crash!

Ora che sono state reperite le informazioni per rendere utile la traccia dell'esecuzione va riprodotto il crash nell'applicazione. La finestra di dialogo di KDE apparirà qualche istante dopo al crash dell'applicazione.

La finestra di dialogo dei crash di KDE
La finestra di dialogo dei crash di KDE

Ora la generazione del backtrace dovrebbe risultare molto più completa, ad esempio:

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

Molto meglio, vero? In questo backtrace sono presenti gli indirizzi di memoria, i file sorgenti, i numeri di riga e i parametri passati alle funzioni che hanno causato il problema. Ciò rende più facile per gli sviluppatori capire la causa del problema, in quanto sanno dove guardare.

Note
È obbligatorio avere GDB installato per ottenere il backtrace di un crash. Nella sezione seguente è spiegato cos'è GDB e come installarlo.


Ottenere un backtrace con GDB

In alcuni casi non è possibile creare un backtrace con la finestra di dialogo dei crash di KDE. Ciò può essere dovuto da un'applicazione entrata in un loop infinito, o dal fatto che la finestra del crash non è apparsa per qualche motivo. In tali casi è possibile ottenere un backtrace con gdb, il Debugger GNU. GDB è disponibile pacchettizzato per tutte le distribuzioni più importanti.

Il richiamo di GDB dipende dalle situazioni. È possibile sia eseguire un'applicazione all'interno di gdb che collegare gdb ad un processo già in esecuzione. Quest'ultima situazione in particolare è utile quando un'applicazione è già entrata in un loop infinito. Cominciamo con la prima soluzione; per eseguire un'applicazione da gdb digitare sulla riga di comando:

$ gdb someKDEapp

Apparirà il prompt di GDB. Per avviare l'applicazione, al momento non ancora avviata, è necessario invocare il comandorun:

(gdb) run
Note
Alcune applicazioni di KDE (ad esempio JuK e KTorrent) contengono del codice speciale per assicurarsi che ci sia una sola istanza dell'applicazione avviata alla volta. Per queste applicazioni bisogna utilizzare il comando "run --nofork" al prompt di (gdb) invece di "run" perché altrimenti gdb proverebbe a debuggare il processo sbagliato. In caso di dubbio su quale usare è sufficiente provare ad avviare l'applicazione con l'opzione --nofork: se l'applicazione dice che è un'opzione sconosciuta è possibile rimuovere l'opzione --nofork.


Questo avvierà l'applicazione a cui siete abituati, e vi permetterà di lavorarci come fate solitamente (con la differenza che consumerà molta più memoria e potrebbe risultare molto più lenta). Ora va riprodotto il crash. Quando l'applicazione va in crash essa si chiuderà riportando al prompt di GDB. Ora è necessario invocare il comando 'backtrace':

(gdb) thread apply all backtrace

Ciò dovrebbe fornire una buona backtrace che può essere inserita nel Bugzilla di KDE.

In caso si voglia collegarsi ad un processo già esistente va invocato il seguente comando:

$ gdb someKDEapp pid

dove pid è il process ID del processo al quale ci si vuole collegare. Una volta collegati, quando il processo è in un ciclo infinito, dopo aver usato il comando 'backtrace' apparirà una traccia dell'esecuzione. È possibile utilizzare il comando 'continue' per lasciare l'applicazione eseguire nuovamente e premere Ctrl+C in gdb per poter inserire nuovamente dei comandi.

Ottenere un backtrace con Valgrind

Un altro strumento utile per creare backtrace di crash è Valgrind; esso non sostituisce GDB, ma piuttosto lo completa.

Quando si esegue un'applicazione in valgrind ogni pezzo di memoria letta o scritta dall'applicazione stessa viene controllato. Valgrind riporterà operazioni non valide in memoria nello standard output o in un file di log. Dato che la maggior parte dei crash sono dovuti a letture invalide in memoria, Valgrind può essere utile per tracciare dove succedono i problemi.

Note
Valgrind consiste di vari tool per verificare o effettuare la profilazione di un'applicazione. In questo articolo useremo solo memcheck, il tool di default che viene chiamato all'esecuzione di valgrind.


Come GDB, Valgrind rende l'esecuzione delle applicazioni molto più lento e più esoso in termini di risorse.

Per avviare l'applicazione all'interno di valgrind:

$ valgrind --log-file=someKDEapp someKDEapp

Ora va riprodotto il crash. Appena avviene sia l'applicazione che valgrind termineranno. Ciò che rimane è un file con nome someKDEapp.pid dove pid sarà il process ID del processo valgrind. Il file potrebbe elencare più errori di quanti siano effettivamente causa del crash. Qui c'è un esempio della parte che causa il crash che corrisponde al backtrace GDB sopra:

==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

Per essere sicuro allega alla segnalazione del bug l'intero file log fornito da valgrind.