Apport_it
Cosa è questa storia?
Il debugging dei crash di un programma senza l'ausilio di strumenti automatici, rappresenta dispendio di tempo e difficoltà da ambo le parti, sviluppatore e segnalatore. Molti crash di programmi non vengono riportati o non vengono riparati poichè:
- Molti crash non sono facilmente riproducibili.
L'utente finale non sa come allestire una segnalazione realmente utile agli sviluppatori, come compilare un pacchetto con i simboli di debug, utilizare gdb, ecc.
- Una considerevole parte del lavoro di triage del bug è spesa nella raccolta di informazioni sul crash stesso, versioni del pacchetto, sistema operativo, architettura hardware, ecc.
- Non c'è una semplice interfaccia che consente all'utente di eseguire una segnalazione dettagliata.
- Le soluzioni esistenti come bug-buddy o krash sono specifiche di un particolare ambiente desktop, e di non facile adattabilità alle necessità di uno sviluppatore di distribuzione, non funzionano per i crash dei server in background (tipo un database o un server email), e non si integrano bene con gli esistenti pacchetti di debug forniti dalla distribuzione.
Apport è un sistema che
- intercetta il crash all'origine,
- raccoglie informazioni potenzialmente utili sul crash e l'ambiente del sistema operativo,
- può essere automaticamente invocato per eccezioni non gestite in altri linguaggi di programmazione (es. in Ubuntu ciò avviene per Python),
- può essere automaticamente invocato da altri programmi per altri problemi che possono essere automaticamente rilevati (es. Ubuntu rileva e segnala automaticamente errori di installazione/aggiornamento di pacchetti da update-manager),
- fornisce una UI che informa l'utente del crash e lo istruisce su come proseguire,
- è anche in grado di segnalare bug non bloccanti sul software, fornendo allo sviluppatore utili informazioni come versione pacchetto, sistema operativo, ecc.
Noi siamo convinti che ciò porterà in futuro alla garanzia di un sempre più alto livello di qualità.
Se si vuole rendere la segnalazione di crash di un proprio programma sempre più utile attraverso Apport, preghiamo consultare /DeveloperHowTo.
Cosa appare all'utente?
L'interfaccia utente di Apport è disegnata per essere semplice e minimamente invasiva.
Se un processo nel sistema muore a causa di un segnale riconducibile ad un 'crash' (segmentation violation, bus error, floating point exception, ecc.), oppure es. una applicazione Python pacchetizzata solleva un eccezione non catturata, il demone di Apport viene automaticamente invocato e produce un iniziale segnalazione in un file situato in /var/crash/ (il nome del file è composto dal nome dell'eseguibile andato in crash e l'id utente). Se il processo andato in crash appartiene all'utente attualmente loggatoo appartiene ad un processo di sistema e l'utente loggato è un amministratore Apport informerà l'utente del crash e ne proporrà la segnalazione:
Ora è possibile fare click su "Mostra dettagli" per vedere quali dati sono stati raccolti:
Se l'utente lascia il checkbox "Inviare una segnalazione...." abilitato, Apport caricherà tutte le informazioni raccolte sul sistema di tracciamento dei bug. Dopodichè apirà la pagina per la segnalazione con il pertinente titolo già impostato, lasciando all'utente il solo compito di inserire una dettagliata descrizione del problema.
Come abilitare Apport
Nei rilasci stabili, Apport è disabilitato anche se è comunque installato. Ci sono due modi per abilitarlo.
- Se si vuole fare il debug di uno specifico programma una sola volta:
sudo service apport start force_start=1
Quindi voi potrete ancora agganciare il crash e la finestra di dialogo di Apport apparirà ancora con le istruzioni per segnalare un bug con valide tracce. Apport sarà automaticamente disabilitato al prossimo avvio.
Se state eseguendo il triaging dei bugs, questo è il miglior modo per ottenere tracce da eventuali segnalatori che non hanno usato Apport.
- Per abilitarlo permanentemente:
sudo nano /etc/default/apport
... e cambiare enabled da "0" a "1".
Il componente di Apport che intercetta automaticamente i crash viene disabilitato nei rilasci stabili per una serie di valide ragioni:
Apport raccoglie dati potenzialmente sensibili quali i core dumps, le stack traces ed i file di log. Essi possono contenere password, numeri di carte di credito, numeri di serie ed altre informazioni private.
Ciò viene mitigato dal fatto che vi viene mostrato cosa sarà inviato al bug tracker e che la segnalazione sarà privata, cioè visibile solamente al the Ubuntu bug triaging team. Noi possiamo ragionevolmente aspettarci che sviluppatori ed utenti tecnicamente colti, che eseguono una versione in fase di sviluppo, siano consapevoli di ciò e sappiano valutare se è opportuno presentare o meno la segnalazione di crash. Ma non possiamo presumere che ogni utente di ubuntu lo sappia fare.
- Durante la fase di sviluppo, riceviamo già migliaia di segnalazioni di crash, molte più di quelle che potremmo mai fixare. Continuare a raccoglierle per il rilascio stabile non è particolarmente utile in quanto:
- I più importanti crash sono già stati scoperti durante la fase di sviluppo.
I meno importanti non sono adatti ad essere fixati in un rilascio stabile (vedere https://wiki.ubuntu.com/StableReleaseUpdates
- Richiedere agli utenti di inviare segnalazioni di crash non è molto sincero, perchè non abbiamo la concreta possibilità di analizzarle tutte.
- La raccolta dei dati con Apport impegna non poco la CPU e le risorse di I/O, che rallentano il computer e non consentono di riavviare l'applicazione crashata per molti secondi.
Nota apport non cattura i segnali SIGABRT. In presenza di uno di questi segnali, consultare DebuggingProgramCrash.
Sono uno sviluppatore. Come faccio ad usare queste segnalazioni?
Il formato della segnalazione
Apport usa lo standard Debian del controllo di sintassi per le segnalazioni, infatti raccoglie tutto in un semplice file simile a questo:
DistroRelease: Ubuntu 12.04 ExecutablePath: /usr/bin/gcalctool Package: gcalctool 5.8.24-0ubuntu2 ProcCmdline: gcalctool ProcEnviron: SHELL=/bin/bash PATH=/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games LANG=de_DE.UTF-8 StackTrace: [...] #0 0x00002ae577bb37bf in poll () from /lib/libc.so.6 No symbol table info available. #1 0x00002ae57786991e in g_main_context_check () from /usr/lib64/libglib-2.0.so.0 No symbol table info available. [...] CoreDump: base64 eJzsXQmcFMXV7+XGA0dBREVoDxSPXQYEB...
Qui sopra è visualizzata solo una piccola parte dei campi contenuti. La segnalazione Apport include un core dump in un formato compresso e codificato, che risulta utile al debugging post-mortem ed alla generazione di una stack trace simbolica.
Comunque, durante il caricamento dei dati sul tracker, potrebbe essere usato un formato differente, ad esenpio utilizzando Launchpad i dati vengono caricati in formato Multipart/MIME, così le parti piccole saranno direttamente nel sommario della segnalazione mentre le più estese saranno allegate separatamente.
Campi
Alcuni campi necessitano di ulteriori approfondimenti:
SegvAnalysis: esaminando un Segmentation Fault (signal 11), Apport tenta di esaminare l'esatta istruzione macchina che ha causato l'errore, controlla il program counter, il sorgente e gli indirizzi di destinazione, alla ricerca di qualsiasi indirizzo di memoria virtuale (VMA) che è al di fuori della gamma allocata (come descritto nell allegato ProcMaps).
SegvReason: un VMA può essere letto, scritto, o eseguito. In un SegFault una di queste 3 azioni della CPU o è avvenuta in un dato VMA che non era allocato, oppure non sussistevano i permessi per l'esecuzione dell'azione. Per esempio:
SegvReason: reading NULL VMA, sta a singificare che un puntatore NULL è stato molto probabilmente dereferenziato durante la lettura di un valore.
SegvReason: writing unknown VMA, sta a significare che qualcosa stava tentando di scrivere alla destinazione di un puntatore puntato al di fuori della memoria allocata. (A volte questo è un problema di sicurezza).
SegvReason: executing writable VMA [stack], sta a significare che qualcosa stava tentando l'esecuzione di codice nello stack, ma quest'ultimo, (correttamente) non aveva i permessi di esecuzione. (Questo è quasi sempre un problema di sicurezza.)
Strumenti
Ci sono molti strumenti per poter lavorare con una segnalazione di crash:
Ubuntu Bug Patterns: Questi sono modelli per pacchetti (scrivibili dal Ubuntu Bug Control) che impediscono la segnalazione ell'anomalia da parte di Apport. Per una descrizione più approfondita consultare README.
apport-unpack: Spacchettizza una segnalazione in singoli file (uno per attributo). Risulta molto utile quando si deve estrarre un core dump. Per ulteriori dettagli consultare il manuale. Questo strumento non è necessario quando si lavora con Launchpad, dato che ha già separato le parti in singoli allegati.
apport-retrace: Rigenera le stack traces di una segnalazione. Con l'aggiunta dell'opzione -g, questo strumento scaricherà automaticamente i relativi pacchetti contenenti la simbologias di debugging e li usarà per generare una stack trace simbolica. Il manuale spiega la funzionalità e tutte le opzioni disponibili.
python-problem-report: Questo pacchetto incorpora il modulo Python problem_report che fornisce un dizionario generale per formulare una segnalazione di crash e metodi di caricamento/salvataggio (non specifici alle segnalazioni di apport).
python-apport: Questo incorpora il pacchetto Python apport che incapsula le funzionalità interne di apport ed è specifico alla rilevazione e segnalazione del crash. Può essere usato per implementare personali frontend e backend.
apport-collect: Questo controlla il pacchetto(i) in una segnalazione già esistente in Launchpad, esegue apport hooks per quel bug e carica le informazioni raccolte allegandole alla segnalazione.
Come funziona internamente?
Come intercetta il crash
Apport usa /proc/sys/kernel/core_pattern direttamente incanalato nel core dump al suo interno. per intercettare i crash Python, installa un /etc/python*/sitecustomize.py per chiamare Apport su eccezioni non gestite.
Backend
Con la premessa di mantenere il ritardo e l'impatto CPU/IO il più basso possibile, /usr/share/apport/apport raccoglie solo dati acquisibili durante il crash: informazioni da /proc/pid, il core dump, il pèercorso dell'eseguibile, ed il numero del segnale. il file viene scritto in /var/crash/executable_path.uid.crash.
Chiamata del Frontend
In Gnome, update-notifier mantiene un controllo inotify in /var/crash. Quando avviene qualcosa di nuovo, chiama /usr/share/apport/apport-checkreports. Se ci sono nuove segnalazioni, chiama /usr/share/apport/apport-gtk, che è uno dei frontend mostrati nelle immagini precedenti.
Quindi il frontend raccoglie informazioni aggiuntive come la versione del pacchetto, il file dei checksum, oppure la versione del sistema operativo, e chiama tutti i corrispondenti agganci Apport relativi al pacchetto.
Launchpad-based auto-retracer
Il Canonical data center esegue un servizio che automaticamente ritraccia le segnalazioni di Apport. Etichettando le segnalazioni in Launchpad in base all'architettura verra eseguita la ritraccia e l'etichetta verrà rimossa. Le etichette usate sono, need-i386-retrace o need-amd64-retrace. Vediannouncement.
Agganci Apport per-pacchetto
È possibile, per i pacchetti, specificare quali informazioni raccoglere dal sistema per essere incluse nella segnalazione. Ciò è fattibile traminte gli agganci Apport contenuti nei pacchetti. Per qualche utile esempio vedere:
- source_xorg.py - adds additional log files and hardware details to bug reports
- usplash - ignores crashes in specific code paths
- source_totem.py - asks the reporter questions and gathers different information based on responses
in /usr/share/apport/package-hooks. There is also a list of packages providing apport hooks.
Consultare /DeveloperHowTo per ulteriori informazioni.
Se un crash o una segnalazione di anomalia avvengono tramite Apport, i relativi agganci saranno eseguiti automaticamente. Se si è già segnalato il bug senza l'ausilio di Apport e siete interessati alle informazioni provenienti da questi agganci, richiedere l'esecuzione di apport-collect bugnumber (see #Strumenti).
Use the source, Luke!
È possibile scaricare il tarball upstream da Launchpad project page, oppure il tarball sorgente Ubuntu da Ubuntu archive.
Apport è sviluppato con il bazaar RCS su Launchpad. Se si desidera contribuire o se si vuole sviluppare un proprio systema basato su Apport, è possibile ottenere unproprio ramo con bzr get lp:apport per il trunk, o debcheckout -a apport per il ramo Ubuntu packaging.
Alternativamente browse it online.
Piani futuri
Varie migliorie alle performace, migliori strumenti per lavorare con le segnalazioni ed integrazione di più linguaggi (Mono/Python stack traces, assertion messages, ecc.) vedere relative specification.
Ulteriori links
Original specifications: apport design, User interface
Please do not hesitate to report bugs and feature requests to the bug tracker.
See Bugs/ApportRetraces for additional documentation for those triaging Apport-generated bug reports in LaunchPad, based on a MOTU/School session by EmmetHikory .
Brian Murray gave a class at Ubuntu Developer week regarding writing package hooks.
Integration using LaunchpadIntegration: https://wiki.ubuntu.com/UbuntuDevelopment/Internationalisation/Coding#LPI
Apport_it (last edited 2012-05-17 15:39:55 by dynamic-adsl-78-14-229-79)