Ghid pentru Raportarea Bug-urilor în Gentoo
1.
Introducere
Prefaţă
Unul din factorii care întârzie repararea unei probleme este modul în care
aceasta este raportată. Prin crearea acestui ghid, sperăm să
îmbunătăţim comunicarea dintre developer şi utilizator. Repararea
problemelor raportate de utilizatori este o componentă foarte importantă,
dacă nu crucială, a calităţii unui proiect, şi sperăm să devină
un succes.
Bugs!!!!
În timp ce rulaţi comanda emerge sau în timp ce rulaţi un program şi
ceea ce n-ar trebui să se întâmple se întâmplă -- aţi găsit un bug!
Bug-urile vin în diferite forme, cum ar fi probleme de emerge sau segmentation
faults. Indiferent care este cauza, o asemenea problemă trebuie rezolvată.
Câteva exemple de bug-uri:
Cod 1.1: Eroare de rulare a programului |
$ ./bad_code `perl -e 'print Ax100'`
Segmentation fault
|
Cod 1.2: Eroare de emerge |
/usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.2/include/g++-v3/backward/backward_warning.h:32:2:
warning: #warning This file includes at least one deprecated or antiquated
header. Please consider using one of the 32 headers found in section 17.4.1.2 of
the C++ standard. Examples include substituting the <X> header for the <X.h>
header for C++ includes, or <sstream> instead of the deprecated header
<strstream.h>. To disable this warning use -Wno-deprecated.
In file included from main.cc:40:
menudef.h:55: error: brace-enclosed initializer used to initialize `
OXPopupMenu*'
menudef.h:62: error: brace-enclosed initializer used to initialize `
OXPopupMenu*'
menudef.h:70: error: brace-enclosed initializer used to initialize `
OXPopupMenu*'
menudef.h:78: error: brace-enclosed initializer used to initialize `
OXPopupMenu*'
main.cc: In member function `void OXMain::DoOpen()':
main.cc:323: warning: unused variable `FILE*fp'
main.cc: In member function `void OXMain::DoSave(char*)':
main.cc:337: warning: unused variable `FILE*fp'
make[1]: *** [main.o] Error 1
make[1]: Leaving directory
`/var/tmp/portage/xclass-0.7.4/work/xclass-0.7.4/example-app'
make: *** [shared] Error 2
!!! ERROR: x11-libs/xclass-0.7.4 failed.
!!! Function src_compile, Line 29, Exitcode 2
!!! 'emake shared' failed
|
Aceste probleme sunt foarte neplăcute. Ce trebuie să faceţi odată ce au
fost detectate? Următoarele secţiuni descriu două unelte importante
folosite în repararea erorilor descoperite în timpul rulării programelor.
Apoi, vom arunca o privire la erorile de compilare. Să începem cu prima
unealtă de depanare a problemelor de rulare -- gdb.
2.
Depanare folosind GDB
Introducere
GDB, sau (G)NU (D)e(B)ugger, este un program folosit pentru diacnosticarea
problemelor de corupţie de memorie. Mai întâi, să vedem în ce constă
procesul de depanare. Primul lucru care trebuie făcut este să emerge
programul cu FEATURES="nostrip". Aceasta, va împiedica eliminarea
simbolurilor de depanare din executabil. De ce se elimină această
informaţie în mod uzual? Din acelaşi motiv pentru care paginile de manual
sunt păstrate de sistem în formă compresată -- salvare de spaţiu pe
hard disc. Iată un exemplu de executabil cu şi fără simboluri de
depanare.
Cod 2.1: Comparare a mărimii executabilelor |
-rwxr-xr-x 1 chris users 3140 6/28 13:11 bad_code
-rwxr-xr-x 1 chris users 6374 6/28 13:10 bad_code
|
Pentru referinţă, bad_code este programul pe care îl vom depana
folosind gdb mai târziu. După cum se vede, programul fără
simboluri debug are o mărime de 3140 bytes, în timp ce programul cu
simboluri are 6374 bytes, adică aproape dublu! Două alte lucruri pot fi
făcute pentru a uşura depanarea. Primul este adăugarea ggdb3 la CFLAGS
şi CXXFLAGS. Acest indicator adaugă mai multă informaţie debug decât
în mod normal. Vom vedea mai târziu ce înseamnă aceasta. Iată cum ar
putea arăta fişierul /etc/make.conf cu noii indicatori
adăugaţi.
Cod 2.2: setare make.conf |
CFLAGS="-O1 -pipe -g -ggdb"
CXXFLAGS="${CFLAGS}"
|
Apoi, puteţi adăuga debug între indicatorii USE corespunzători pachetului
respectiv. Aceasta se poate face modificând fişierul
package.use.
Cod 2.3: Folosirea package.use pentru a adăuga debug între indicatorii USE |
# echo "category/package debug" >> /etc/portage/package.use
|
Notă:
Dacă directorul /etc/portage nu există implicit, va trebui
să fie creat, dacă un aţi făcut-o deja. Dacă pachetul are deja
indicatori USE setaţi în package.use, va trebui să modificaţi
fişierul într-un editor de text.
|
Apoi reinstalaţi pachetul cu modificările de mai sus după cum se arată
mai jos.
Cod 2.4: Reinstalarea pachetului cu informaţie pentru depanare |
# FEATURES="nostrip" emerge pachet
|
Acum, că simbolurile sunt incluse, putem începe operaţia de depanare.
Rularea programului folosind GDB
Să presupunem că avem un program numit "bad_code". Cineva susţine că
programul returnează eroare şi ne dă un exemplu. Începem testarea:
Cod 2.5: Facem programul să returneze eroare |
$ ./bad_code `perl -e 'print Ax100'`
Segmentation fault
|
Se pare că utilizatorul a avut dreptate, acesta este în mod clar un bug. A
venit timpul să ne folosim de gdb pentru a diagnostica această
problemă. Pentru început rulăm gdb cu --args, apoi îi dăm
întregul program cu argumentele descrise mai jos:
Cod 2.6: Rularea programului prin GDB |
$ gdb --args ./bad_code `perl -e 'print Ax100'`
GNU gdb 6.3
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".
|
Notă:
Putem de asemenea să folosim "core dumps". Aceste fişiere conţin aceeaşi
informaţie care este produsă de gdb. Pentru depanarea bad_code folosind un
fişier core va trebui să rulaţi gdb ./bad_code core unde core este
numele fişierului core.
|
Ar trebui să vedeţi un prompt intitulat "(gdb)" care aşteaptă comenzi.
Mai întâi pornim programul. Introducem run drept comandă de prompt
şi primim înapoi ceva de genul:
Cod 2.7: Rularea programului în GDB |
(gdb) run
Starting program: /home/chris/bad_code
Program received signal SIGSEGV, Segmentation fault.
0xb7ec6dc0 in strcpy () from /lib/libc.so.6
|
Vedem aici programul pornind şi primind notificarea SIGSEGV sau Segmentation
Fault. Acesta este GDB spunându-ne că programul a eşuat. De asemenea, ne
spune care a fost ultima funcţie care a rulat înainte de crash. Totuşi,
informaţia nu este teribil de folositoare, există nenumărate locuri în
program unde funcţia strcpy este chemată, şi este dificil de determinat
care din ele a generat problema. Pentru a ajuta pe developer trebuie să
generăm ceea ce se numeşte un backtrace. Un backtrace este o listă a
funcţiilor care au fost executate în succesiune de program, terminând cu
funcţia care a generat crash-ul. Funcţiile care au fost returnate fără
crash nu apar în backtrace. Pentru a genera backtrace-ul, introduceţi comanda
bt în promptul gdb. Veţi obţine ceva de genul:
Cod 2.8: Backtrace pentru aplicaţie |
(gdb) bt
#0 0xb7ec6dc0 in strcpy () from /lib/libc.so.6
#1 0x0804838c in run_it ()
#2 0x080483ba in main ()
|
Backtrace-ul ne spune că funcţia main() a fost chemată prima, urmată de
funcţia run_it(), iar undeva în această funcţie se găseşte apelul
funcţiei strcpy() care a generat problema. Există un număr mic de
excepţii când un backtrace nu ne oferă informaţia pe care o căutăm.
Primul este cazul în care uităm să adăugăm simboluri de depanare cu
FEATURES="nostrip". În acest caz, backtrace-ul arată în felul
următor:
Cod 2.9: Backtrace fără simboluri de depanare |
(gdb) bt
#0 0xb7e2cdc0 in strcpy () from /lib/libc.so.6
#1 0x0804838c in ?? ()
#2 0xbfd19510 in ?? ()
#3 0x00000000 in ?? ()
#4 0x00000000 in ?? ()
#5 0xb7eef148 in libgcc_s_personality () from /lib/libc.so.6
#6 0x080482ed in ?? ()
#7 0x080495b0 in ?? ()
#8 0xbfd19528 in ?? ()
#9 0xb7dd73b8 in __guard_setup () from /lib/libc.so.6
#10 0xb7dd742d in __guard_setup () from /lib/libc.so.6
#11 0x00000006 in ?? ()
#12 0xbfd19548 in ?? ()
#13 0x080483ba in ?? ()
#14 0x00000000 in ?? ()
#15 0x00000000 in ?? ()
#16 0xb7deebcc in __new_exitfn () from /lib/libc.so.6
#17 0x00000000 in ?? ()
#18 0xbfd19560 in ?? ()
#19 0xb7ef017c in nullserv () from /lib/libc.so.6
#20 0xb7dd6f37 in __libc_start_main () from /lib/libc.so.6
#21 0x00000001 in ?? ()
#22 0xbfd195d4 in ?? ()
#23 0xbfd195dc in ?? ()
#24 0x08048201 in ?? ()
|
Acest backtrace conţine un număr mare de ??, deoarece fără simboluri de
depanare, gdb nu ştie cum a fost rulat programul. De aceea este
esenţial să avem simboluri de depanare în executabil. Mai devreme am
menţionat indicatorul -ggdb. Să vedem cum arată backtrace-ul nostru cu
acest indicator activ:
Cod 2.10: Backtrace pentru un program cu indicatorul -ggdb3 activ |
(gdb) bt
#0 0xb7e4bdc0 in strcpy () from /lib/libc.so.6
#1 0x0804838c in run_it (input=0x0) at bad_code.c:7
#2 0x080483ba in main (argc=1, argv=0xbfd3a434) at bad_code.c:12
|
Mult mai multă informaţie este disponibilă în acest caz. Nu numai numele
funcţiei dar şi numărul liniei de cod sursă este disponibil. Aceasta
este metoda preferată, preţul plătit este o creştere a dimensiunilor
executabilului. Iată cum variază această dimensiune pentru un program cu
sau fără simboluri de depanare, şi cu indicatorul -ggdb activ:
Cod 2.11: Diferenţe în mărimea programului cu indicatorul -ggdb |
-rwxr-xr-x 1 chris users 3140 6/28 13:11 bad_code
-rwxr-xr-x 1 chris users 6374 6/28 13:10 bad_code
-rwxr-xr-x 1 chris users 19552 6/28 13:11 bad_code
|
După cum se vede, -ggdb adaugă 13178 octeţi la executabil comparat
cu versiunea cu simboluri de depanare însă -ggdb inactiv. Această
creştere în dimensiune poate fi esenţială când informaţia este
prezentată dezvoltatorilor. Backtrace-ul poate fi salvat într-un fişier
text prin copy şi paste din terminal (dacă este un terminal non-x puteţi
folosi gpm. Pentru a simplifica acest document, recomand să consultaţi
documentaţia gpm). După ce terminăm cu gdb, putem ieşi din acest
program.
Cod 2.12: Ieşirea din GDB |
(gdb) quit
The program is running. Exit anyway? (y or n) y
$
|
Aceasta încheie demonstraţia noastră de gdb. Folosind gdb
sperăm că veţi crea rapoarte de bug-uri mai bune. Există totuşi alte
tipuri de probleme care pot rezulta într-o eroare a programului, de exemplu
acces impropriu de fişiere. Pentru a diagnostica o asemenea problemă
folosim programul utilitar strace.
3.
Diagnosticarea problemelor de acces de fişiere folosind strace
Introducere
Deseori, programele folosesc alte fişiere pentru a obţine informaţia de
configuraţie, pentru a accesa informaţille hardware sau pentru a scrie
jurnalele. Uneori, programele încearcă să acceseze aceste fişiere în
mod incorect. Pentru a diagnostica astfel de probleme se foloseşte utilitarul
strace. Acest utilitar trasează toate apelurile de sistem (de aici
şi numele) care includ toate accesele la memorie şi fişiere. Luăm ca
exemplu un program numit foobar. În timpul trecerii la foobar2 observăm
că toată informaţia de configurare lipseşte! Foobar versiunea 1
utilizează configuraţia din "foo" în timp ce foobar2 caută configuraţia
în "bar".
Cod 3.1: Foobar2 cu configuraţie invalidă |
$ ./foobar2
Configuration says: bar
|
Versiunea originală folosea configuraţia setată în foo, deci să
încercăm strace să vedem ce se întâmplă.
Folosirea strace pentru a investiga problema
Folosim strace pentru a obţine o listă a call-urilor sistem. Pentru
aceasta rulăm strace cu argumentul -o[file]. Să încercăm astfel
pentru foobar2.
Cod 3.2: Rularea foobar2 prin strace |
# strace -ostrace.log ./foobar2
|
Această comandă crează un fişier intitulat strace.log în
directorul curent. Verificăm fişierul, părţile relevante sunt descrise
mai jos.
Cod 3.3: Verificarea strace Log |
open(".foobar2/config", O_RDONLY) = 3
read(3, "bar", 3) = 3
|
Aha! Deci aceasta era problema. Cineva a modificat numele directorului de
configurare din .foobar în .foobar2. De asemenea,
programul citeşte fişierul "bar" după cum trebuie. În acest caz
recomandăm ca maintainer-ul ebuild-ului să afişeze un avertisment.
Temporar pentru a ne rezolva problema, putem copia configuraţia din
.foobar şi o putem modifica pentru a obţine rezultate corecte.
Concluzii
În acest mod sunt diagnosticate problemele de rulare a programelor. Aceste
probleme devin vizibile numai în cazul în care programul este rulat. În
unele cazuri nu ajungem atât de departe, s-ar putea ca programul nici să nu
compileze. Să vedem cum se diagnostichează problemele de compilare
rezultate la emerge.
4.
Diagnosticarea problemelor emerge
Introducere
Erorile emerge sunt un caz major de frustrare pentru utilizatori.
Raportarea lor este crucială pentru Gentoo. Să aruncăm o privire la un
ebuild intitulat foobar2 care conţine erori de compilare.
Diagnosticarea erorilor emerge
Presupunem următoarea eroare emerge simplă:
Cod 4.1: eroare emerge |
gcc -D__TEST__ -D__GNU__ -D__LINUX__ -L/usr/lib -I/usr/include -L/usr/lib/nspr/ -I/usr/include/fmod -c -o foobar2-7.o foobar2-7.c
gcc -D__TEST__ -D__GNU__ -D__LINUX__ -L/usr/lib -I/usr/include -L/usr/lib/nspr/ -I/usr/include/fmod -c -o foobar2-8.o foobar2-8.c
gcc -D__TEST__ -D__GNU__ -D__LINUX__ -L/usr/lib -I/usr/include -L/usr/lib/nspr/ -I/usr/include/fmod -c -o foobar2-9.o foobar2-9.c
gcc -D__TEST__ -D__GNU__ -D__LINUX__ -L/usr/lib -I/usr/include -L/usr/lib/nspr/ -I/usr/include/fmod -c -o foobar2.o foobar2.c
foobar2.c:1:17: ogg.h: No such file or directory
make: *** [foobar2.o] Error 1
!!! ERROR: sys-apps/foobar2-1.0 failed.
!!! Function src_compile, Line 19, Exitcode 2
!!! Make failed!
!!! If you need support, post the topmost build error, NOT this status message
|
Toate merg bine până când compilarea se opreşte brusc cu un mesaj de
eroare. Această eroare particulară poate fi împărţită în trei
secţiuni: mesajul de compilare, eroarea de build şi eroarea de emerge după
cum se arată mai jos.
Cod 4.2: Componente ale erorii |
gcc -D__TEST__ -D__GNU__ -D__LINUX__ -L/usr/lib -I/usr/include -L/usr/lib/nspr/ -I/usr/include/fmod -c -o foobar2-7.o foobar2-7.c
gcc -D__TEST__ -D__GNU__ -D__LINUX__ -L/usr/lib -I/usr/include -L/usr/lib/nspr/ -I/usr/include/fmod -c -o foobar2-8.o foobar2-8.c
gcc -D__TEST__ -D__GNU__ -D__LINUX__ -L/usr/lib -I/usr/include -L/usr/lib/nspr/ -I/usr/include/fmod -c -o foobar2-9.o foobar2-9.c
gcc -D__TEST__ -D__GNU__ -D__LINUX__ -L/usr/lib -I/usr/include -L/usr/lib/nspr/ -I/usr/include/fmod -c -o foobar2.o foobar2.c
foobar2.c:1:17: ogg.h: No such file or directory
make: *** [foobar2.o] Error 1
!!! ERROR: sys-apps/foobar2-1.0 failed.
!!! Function src_compile, Line 19, Exitcode 2
!!! Make failed!
!!! If you need support, post the topmost build error, NOT this status message
|
Mesajele de compilare stau la baza erorii. În general, este bine să
includem cel puţin 10 linii cu informaţie de compilare, pentru a-l informa pe
developer unde exact se afla compilarea.
Erorile de build (sau erori de make) sunt erorile în sine, şi este ceea ce
developer-ul are nevoie. Când vedeţi "make: ***", acesta este în general
locul în care eroarea s-a produs. În general puteţi copy şi paste 10
linii deasupra erorii make iar dezvoltatorul va putea rezolva problema. În
cazul în care aceasta nu este suficient, vom vedea ulterior o alternativă.
Eroarea emerge este generată de utilitarul emerge. Adeseori,
utilizatorii fac greşeala să trimită dezvoltatorului numai această
informaţie. În sine, această informaţie singură este total irelevantă
pentru dezvoltator, însă împreună cu eroarea de compilare şi cea de
build îi spune acestuia ce aplicaţie şi ce versiune a pachetului are
problema. Ca o notă separată, make nu este întodeauna folosit în procesul
de build. Dacă nu puteţi găsi eroarea "make: ***", copy şi paste 20 de
linii înainte de mesajul de eroare. Aceasta va fi suficient în majoritatea
cazurilor. Să presupunem că eroarea este deosebit de mare şi 10 linii nu
sunt suficiente. În acest caz ne folosim de PORT_LOGDIR.
emerge şi PORT_LOGDIR
PORT_LOGDIR este o variabilă portage care setează directorul de log pentru
emerge. Să aruncăm o privire să vedem ce înseamnă aceasta. Mai
întâi, rulaţi emerge setând PORT_LOGDIR pentru locaţia dumneavostră
favorită. Să presupunem că dorim să o setăm ca
/var/log/portage.
Notă:
Implicit, această locaţie nu există şi va trebui să o creem. Dacă
nu, portage nu va fi capabil să scrie log-urile.
|
Cod 4.3: emerge cu PORT_LOGDIR |
# PORT_LOGDIR=/var/log/portage emerge foobar2
|
Acum, emerge va eşua din nou. Totuşi, în acest caz avem un log cu care
putem lucra. Îl putem ataşa la raport de bug ulterior. Să aruncăm o
privire în directorul de log.
Cod 4.4: Conţinutul directorului PORT_LOGDIR |
# ls -la /var/log/portage
total 16
drwxrws--- 2 root root 4096 Jun 30 10:08 .
drwxr-xr-x 15 root root 4096 Jun 30 10:08 ..
-rw-r--r-- 1 root root 7390 Jun 30 10:09 2115-foobar2-1.0.log
|
Formatul fişierului log este [contor]-[nume pachet]-[versiune].log. Counter
este o variabilă specială al cărui scop este de a număra global
pachetele care au fost emerged. Această variabilă are scopul de a preveni
duplicarea jurnalelor de emerge. O scurtă privire în acest fişiere ne va
arăta întregul proces de emerge. Acest fişier va fi ataşat mai târziu
la raport după cum se descrie în secţiunea referitoare la raportarea
bug-ului. Înainte de a continua mai departe, să vedem cum se face o
căutare pentru bug-uri deja raportate.
5.
Utilizarea Bugzilla pentru a căuta bug-uri raportate deja
Introducere
Gentoo foloseşte Bugzilla pentru
gestionarea bug-urilor. Bugzilla poate fi accesată prin HTTPS şi HTTP.
Folosiţi un protocol sau altul în funcţie de gradul de securitate al
reţelei sau de gradul de paranoia :). Pentru consistenţă vom folosi
versiunea HTTPS în exemplele care urmează. Mergeţi la Gentoo Bugs pentru a vedea cum arată.
Una dintre cele mai neplăcute activităţi pentru dezvoltatori este
găsirea bag-urilor duplicate. Aceasta rezultă în irosirea unei
cantităţi impresionante de timp care ar putea fi utilizat altfel pentru
repararea propriu-zisă a problemei. Deseori, această situaţie poate fi
prevenită printr-un simplu search. Explicăm în continuare cum să
căutăm dacă există deja un bug similar în baza de date. Folosim de
exemplu eroarea emerge xclass folosită anterior.
Cod 5.1: eroare emerge xclass |
/usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.2/include/g++-v3/backward/backward_warning.h:32:2:
warning: #warning This file includes at least one deprecated or antiquated
header. Please consider using one of the 32 headers found in section 17.4.1.2 of
the C++ standard. Examples include substituting the <X> header for the <X.h>
header for C++ includes, or <sstream> instead of the deprecated header
<strstream.h>. To disable this warning use -Wno-deprecated.
In file included from main.cc:40:
menudef.h:55: error: brace-enclosed initializer used to initialize `
OXPopupMenu*'
menudef.h:62: error: brace-enclosed initializer used to initialize `
OXPopupMenu*'
menudef.h:70: error: brace-enclosed initializer used to initialize `
OXPopupMenu*'
menudef.h:78: error: brace-enclosed initializer used to initialize `
OXPopupMenu*'
main.cc: In member function `void OXMain::DoOpen()':
main.cc:323: warning: unused variable `FILE*fp'
main.cc: In member function `void OXMain::DoSave(char*)':
main.cc:337: warning: unused variable `FILE*fp'
make[1]: *** [main.o] Error 1
make[1]: Leaving directory
`/var/tmp/portage/xclass-0.7.4/work/xclass-0.7.4/example-app'
make: *** [shared] Error 2
!!! ERROR: x11-libs/xclass-0.7.4 failed.
!!! Function src_compile, Line 29, Exitcode 2
!!! 'emake shared' failed
|
Începem căutarea la Pagina de Start
Bugzilla.
Figura 5.1: Pagina de Start Bugzilla |
 |
Click pe "Query Existing bug reports". Motivul pentru care folosim aceasta în
loc de o căutare simplu, este că o căutare simplă tinde să dea
rezultate vagi şi, în general, crează probleme utilizatorilor în
găsirea bug-urilor duplicate. După click suntem direcţionaţi la
următoarea pagină.
Figura 5.2: Pagina de Căutare Bugzilla |
 |
Notă:
Dacă aţi mai folosit Advanced Search, veţi vedea probabil acea pagină.
|
Continuaţi prin a apăsa pe "Advanced Search" pentru a ajunge la pagina de
Căutare Avansată.
Figura 5.3: Pagina de Căutare Avansată |
 |
Pagina de Căutare Avansată arată ca mai sus. Deşi pare complicată, ne
vom uita la un număr mic de opţiuni pentru a filtra rezultatele.
Figura 5.4: Conţinut |
 |
În primul câmp intitulat Summary vom pune numele pachetului cu probleme.
Dacă Bugzilla nu returnează nici un rezultat încercaţi fără a
specifica numele pachetului, asta pentru cazurile în care bug-ul nu a fost
raportat utilizând acest nume (foarte puţin probabil însă s-au văzut
cazuri).
Product, Component, şi Version sunt lăsate la valoarea implicită pentru a
nu fi excesiv de specific în cazul în care bug-ul a fost introdus pentru o
altă versiune/componentă/etc.
Comment este cel mai important câmp. Folosiţi-l pentru a detalia problema
specifică. Practic, nu folosiţi nimic de la începutul erorii de build,
folosiţi o linie de dinaintea ei care menţionează eroarea. De asemenea,
înlăturaţi orice punctuaţie pentru a împiedica Bugzilla să interpreteze
rezultatele în mod greşit. Exemplu din eroarea emerge xclass:
Cod 5.2: Conţinutul liniei de comentariu |
menudef.h:78: error: brace-enclosed initializer used to initialize `OXPopupMenu'
menudef.h 78 error brace-enclosed initializer used to initialize OXPopupMenu
|
Conţinutul de mai sus este destul de specific pentru a găsi bug-ul, fără
a intra în alte probleme de compilare ale xclass.
URI, Whiteboard şi Keywoards pot fi lăsate nemodificate. Tot ce am introdus
până acum ar trebui să fie suficient să găsim bug-ul. Să vedem ce am
introdus.
Figura 5.5: Formularul de Căutare Complet |
 |
Apăsăm apoi pe butonul Search şi primim rezultatele...
Figura 5.6: Rezultatele Căutării |
 |
Numai două bug-uri! Aceasta este mult mai uşor de verificat. Click pe
primul, şi bineînţeles este ceea ce căutam.
Figura 5.7: Bug-ul Localizat |
 |
Nu numai că l-am găsit, însă a şi fost rezolvat. Verificând ultimul
comentariu, acesta este soluţia pentru bug şi ştim ce trebuie să facem
pentru a-l rezolva. Să vedem acum ce s-ar fi întâmplat dacă nu am fi
apelat la Căutare Avansată.
Figura 5.8: Rezultatele Căutării Simple |
 |
Încă patru bug-uri. Pentru pachete mai mari situaţia este şi mai rea.
Totuşi, folosind aceste unelte simple, putem filtra suficient de bine lista
de bug-uri pentru a-l localiza.
Concluzii
Să presupunem că aţi căutat şi căutat şi nu aţi găsit nimic.
În acest caz aveţi un bug nou. Să vedem cum arată procesul de raportare
a bug-urilor noi.
6.
Reportarea bug-urilor
Introducere
În acest capitol vom descrie modul de utilizare Bugzilla pentru a raporta un
bug nou. Începeţi prin a merge la Gentoo
Bugs şi ...
Figura 6.1: Pagina de Start Bugzilla |
 |
Click pe "Report a Bug - Using the guided format"
Figura 6.2: Specificarea Produsului |
 |
După cum vedeţi accentul major se pune pe introducerea bug-ului în
locul corespunzător. Majoritatea bug-urilor merg la Gentoo Linux.
În ciuda acestui fapt, unii utilizatori vor raporta bug-ul către portage
development (presupunerea este că echipa de dezvoltatori portage este
responsabilă de structura portage) sau infra (prespunerea este că infra are
acces la mirror-uri şi rsync şi poate să rezolve problema în mod
direct). Lucrurile nu stau aşa.
O altă neînţelegere se referă la bug-urile pentru documentaţie. De
exemplu, un utilizator găseşte un bug pe pagina de Documentaţie Catalyst. Tendinţa este
să se posteze un bug sub Docs-user care va fi trimis apoi la GDP (Proiectul de Documentaţie Gentoo),
în loc de Release Engineering. De regulă,
numai documentaţia din http://www.gentoo.org/doc/* este pentru
GDP. Orice document în http://www.gentoo.org/proj/* aparţine
echipei respective.
Notă:
Am prefera să avem un bug care nu aparţine echipei Gentoo Linux decât să
avem un bug Gentoo Linux trimis altundeva. Nici una dintre variante nu este
bună, însă primul caz este acceptat şi înţeles (cu excepţia
bug-urilor referitoare la website.. ar putea să fie o problemă cu
acesta...).
|
Bug-ul nostru va fi postat în Gentoo Linux întrucât este o problemă de
ebuild. Ne ducem acolo şi începem primul pas al procesului...
Figura 6.3: Formatul Ghidat, Pasul 1 |
 |
Primul pas este foarte important, după cum este sugerat şi de textul în
roşu. Acesta este locul unde căutaţi dacă altcineva nu are aceeaşi
problemă. Dacă săriţi peste acest pas şi un bug similar este găsit,
va fi marcat ca DUPLICATE (Duplicat) în detrimentul timpului pierdut de echipa
QA pentru această operaţie. Pentru a vă da o idee, bug-urile de mai sus
sunt marcate drept duplicate. Trecem la pasul al doilea unde introducem mai
multă informaţie.
Informaţie necesară
Figura 6.4: Informaţiile de Bază |
 |
Să vedem despre ce este vorba.
-
În primul rând este Product. Specificând produsul, bug-ul va fi pus
într-o categorie specifică a Bugzilla (pentru bug-uri gentoo.org),
Docs-user (pentru documentaţie) sau Gentoo Linux (pentru ebuild-uri).
-
Component specifică unde se manifestă problema, mai specific în care
parte a produsului problema a fost observată. Aceasta face clasificare
bug-ului mai uşoară.
-
Hardware platform se referă la ce arhitectură rulaţi. Dacă rulaţi
să spunem SPARC, va trebui să setaţi SPARC.
-
Operating System se referă la sistemul de operare pe care îl folosiţi.
Gentoo este o "Meta-distribuţie", şi poate rula şi alte sisteme de
operare pe lângă Linux.
Deci, pentru exemplul nostru avem:
- Product - Gentoo Linux (deoarece este o problemă ebuild)
- Component - Application (este o problemă cu aplicaţia foobar2)
- Hardware Platform - All (Această problemă poate apare pe mai multe arhitecturi)
- Operating System - All (Poate fi întâlnită pe toate tipurile de sistem)
Figura 6.5: Informaţiile de Bază Complete |
 |
-
Build Identifier este variabila User Agent a browser-ului pe care îl
folosiţi pentru a raporta bug-ul (în scopuri de jurnalizare). Poate fi
lăsat neschimbat.
-
URL este opţional, şi poate fi folosit pentru a specifica o pagină web
unde sunt depozitate erorile (pastebin, etc). Motivul pentru care această
informaţie are valoare pentru dezvoltatori este că poate fi folosită
ca referinţă şi este de preferat.
-
În Summary trebuie să puneţi categoria pachetului, numele şi
numărul.
A nu include categoria pachetului în Summary nu este rău, însă se
recomandă. Dacă însă numele pachetului nu este inclus, este greu de spus
la ce se referă bug-ul şi va trebui să vă întrebăm mai târziu.
Numărul versiunii este important pentru toţi utilizatorii care caută prin
lista de bug-uri. Dacă 20 de utilizatori au trimis bug-uri şi nici unul nu
a specificat o versiune, este imposibil pentru cei ce vor căuta bug-uri mai
târziu să spună dacă este sau nu un bug. În acest caz ar trebui să
se uite pe rând la fiecare bug însă dacă sunt de exemplu 200 de
bug-uri... nu este prea uşor. După informaţia referitoare la pachet
trebuie să includeţi o mică descriere a incidentului. Iată un exemplu:
Figura 6.6: Sumar |
 |
Aceste reguli simple vor uşura prelucrare ulterioară a bug-urilor. În
continuare o serie de detalii. Vom lua un mic exemplu.
Figura 6.7: Detalii |
 |
Cu aceasta dezvoltatorul ştie de ce trimitem bug-ul. Developer-ul va încerca
să îl reproducă. Reproductibilitatea ne spune cât de des putem face ca
problema să se întâmple din nou. În acest caz, o putem reproduce de
fiecare dată rulând foobar2. Să adăugăm această informaţie.
Figura 6.8: Reproductibilitate |
 |
Am explicat deci că am găsit un bug. Următorul pas este să explicăm
ce rezultate am obţinut şi ce credem că ar fi trebuit să conţină.
Figura 6.9: Rezultate |
 |
Orice informaţie adiţională poate fi adăugată. Aceasta poate conţine
stack traces, jurnalul comenzii strace, secţiuni (deoarece întregul
log este foarte mare şi nu foarte folositor), şi cel mai important
rezultatul lui emerge --info pe sistemul dumneavoastră. Un exemplu:
Figura 6.10: Informaţii Adiţionale |
 |
Apoi selectăm severitatea bug-ului. Puţină atenţie este necesară. În
cele mai multe cazuri este OK să o lăsăm aşa cum este şi altcineva o
va mări sau micşora de la caz la caz. Dacă totuşi decideţi să
măriţi severitatea, vă rugăm să citiţi cu atenţie ca să nu faceţi
o greşeală. O explicaţie a nivelelor de severitate o găsiţi mai jos.
-
Blocker - Programul nu vrea să se compileze sau crează probleme în
sistem. De exemplu pachetul baselayout va împiedica boot-area
sistemului şi ar fi un candidat bun pentru nivelul blocker.
-
Critical - programul generează pierderi de date sau pierderi de memorie
în timpul rulării. Din nou, un program important cum ar fi de exemplu
net-toos care nu compilează poate fi introdus pe nivelul critical.
Sistemul va porni, însă pachetul este esenţial pentru funcţionarea
corespunzătoare a sistemului.
-
Major - Crash de program, însă nimic care să distrugă sistemul sau
să pierdeţi informaţie.
-
Minor - Crash de program din când în când, cu posibile posibilităţi
de ocolire.
-
Normal - default. Dacă nu sunteţi sigur lăsaţi bug-ul pe acest nivel.
Dacă este un build nou sau o modificare cosmetică, citiţi mai jos.
-
Trivial - lucruri precum greşeli de ortografie sau spaţii libere de
curăţat.
-
Enhancement - Cerere pentru a implementa o facilitate noua în program sau
mai specific ebuild-uri noi.
Figura 6.11: Severitatea |
 |
Lăsăm nivelul neschimbat, pe Normal.
Trimitem bug-ul apăsând pe butonul Submit Bug Report. Verfificaţi Bug-ul 97561 pentru
a vedea cum arată rezultatul. Am raportat bug-ul! Să vedem ce se
întâmplă cu acesta în continuare.
7.
Manipularea Bug-ului
Dacă ne uităm la bug, vedem informaţia pe care am trimis-o. Vom observa ca
bug-ul a ajuns la bug-wranglers@gentoo.org. Aceasta este locaţia implicită
pentru bug-urile componentei Application.
Figura 7.1: Informaţiile de Bază pentru Noul Bug |
 |
Detaliile introduse de dumneavoastră sunt de asemenea disponibile.
Figura 7.2: Detaliile Noului Bug |
 |
În general cei din echipa bug-wranglers nu vor rezolva bug-ul, acesta va fi
trimis unui developer (puteţi cere bug-wranglers să vi-l trimită
dumneavoastră). Pentru aceasta se foloseşte metadata.xml incorporată în
pachet. O puteţi găsi uzual în
/usr/portage/category/package/metadata.xml. De exemplu pentru
pachetul nostru foobar2:
Notă:
Trebuie să fiţi cel care a raportat bug-ul sau un membru al unui grup Gentoo
Bugzilla specific (ca de exemplu Gentoo Developers) pentru a putea reatribui
bug-ul.
|
Cod 7.1: metadata.xml |
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
<pkgmetadata>
<herd>chriswhite</herd>
<maintainer>
<email>chriswhite@gentoo.org</email>
<name>Chris White</name>
</maintainer>
<longdescription lang="en">
Foobar2 is a package that uses a configuration file to display a word.
</longdescription>
</pkgmetadata>
|
Observaţi secţiunea manitainer. Aceasta listează maintainer-ul pachetului,
care în acest caz sunt eu, Chris White. Adresa de email listată este
chriswhite@gentoo.org. Vom folosi aceasta pentru a reatribui bug-ul persoanei
care trebuie. Click pe Reassign bug to, şi introduceţi adresa de email.
Notă:
Un bug pentru un pachet fără metadata.xml trebuie reatribuit lui
maintainer-needed@gentoo.org iar un pachet care are nevoie de un Gentoo
Developer trebuie trimis la maintainer-wanted@gentoo.org.
|
Figura 7.3: Reatribuirea unui Bug |
 |
Apăsaţi apoi butonul Commit pentru ca schimbarea să aibă loc. Bug-ul
mi-a fost reatribuit mie. Puţin mai târziu, voi răspunde (de regulă prin
email) la bug. Am spus că aş dori să văd un jurnal strace pentru a
înţelege cum încearcă programul să ajungă la fişierele de
configurare. Folosind instrucţiunile anterioare obţineţi un jurnal pe care
îl ataşaţi bug-ului. Pentru aceasta apăsaţi "Create A New Attachement".
Figura 7.4: Ataşament Nou |
 |
Acum, trebuie să ataşăm jurnalul. Haideţi să parcurgem toţi paşii.
-
File - Aceasta este locaţia fişierului pe calculatorul dumneavoastră.
În acest exemplu locaţia este strace.log. Puteţi folosi
butonul "Browse..." pentru a selecta fişierul, sau introduceţi locaţia
direct ca text.
-
Description - O singură linie, cu puţine cuvinte descriind fişierul
ataşat. Introducem starce.log şi se înţelege de la sine.
-
Content Type - Acesta este tipul fişierului ataşat la bug.
-
Obsoletes - Dacă alte fişiere au fost ataşate anterior, aveţi
opţiunea să le declaraţi învechite. În cazul nostru, acesta fiind
primul fişier ataşat, nu ne facem probleme.
-
Comment - Introduceţi orice comentariu referitor la fişier pe care îl
consideraţi relevant, dacă este nevoie.
În ceea ce priveşte Content Type, iată câteva detalii. Puteţi bifa
opţiunea "patch" dacă trimiteţi un patch. Altfel, puteţi cere interfeţei
Bugzilla să autodetecteze tipul fişierului (nerecomandat). Cealaltă
opţiune este "select form list", este cea mai frecvent folosită. Alegeţi
text simplu (text/plain) pentru majoritatea fişierelor, cu excepţia
fişierelor binare cum ar fi imagini (care pot fi image/gif, image/jpeg sau
image/png) sau arhive compresate precum .tar.bz2 care folosesc tipul
application/octet-stream.
Figura 7.5: Ataşament Nou Completat |
 |
Trimitem strace.log şi se reflectată în raport.
Figura 7.6: Jurnalul strace ataşat |
 |
Am menţionat anterior că uneori ebuild-urile vă vor cere să ataşaţi
un fişier în mesajul de eroare. Un exemplu este mai jos.
Cod 7.2: Examplu de Cerere de Ataşare de Fişier |
configure: error: PNG support requires ZLIB. Use --with-zlib-dir=<DIR>
!!! Please attach the config.log to your bug report:
!!! /var/tmp/portage/php-5.0.3-r1/work/php-5.0.3/config.log
!!! ERROR: dev-php/php-5.0.3-r1 failed.
!!! Function econf, Line 485, Exitcode 0
!!! econf failed
!!! If you need support, post the topmost build error, NOT this status message.
|
Vă rugăm să ataşaţi orice fişier menţionat în acest raport.
Să presupunem că în timp ce facem aceasta, o altă persoană găseşte
bug-ul căutând prin bugzilla şi este curios să vadă ce se întâmplă
cu bug-ul. Ar putea să facă aceasta intoducând adresa de email în câmpul
Add CC după cum se arată mai jos. Puteţi în acest fel să urmăriţi
orice bug prin această metodă.
Figura 7.7: Adăugarea Adresei de Email în Câmpul CC: |
 |
Notă:
Adresele de email trebuie să fie înregistrate cu Gentoo Bugzilla. În cazul
când aveţi mai multe adrese, le introduceţi separate prin virgule sau
spaţii.
|
După toată această muncă, bug-ul va trece prin diferite stagii. Aceasta
se face în general de Dezvoltatorii Gentoo şi uneori de către cel ce a
raportat bug-ul. Urmează stadiile variate prin care poate trece un bug în
timpul valabilităţii acestuia.
-
UNCONFIRMED - Nu apare prea des. Aceasta înseamnă că cel care a
raportat bug-ul folosind metoda avansată şi nu este sigur că acesta
este un bug.
-
NEW - Prima oară când bug-ul este deschis, este considerat nou.
-
ASSIGNED - Când persoana căreia bug-ul i-a fost atribuit îl
validează. Bug-ul este pus în acest stagiu în timp ce dezvoltatorul
încearcă să înţeleagă care este problema. Acest stagiu ne
informeză că bug-ul a fost acceptat şi este o problemă reală.
-
REOPENED - Cineva a rezolvat bug-ul iar soluţia nu pare să rezolve
problema. În acest caz, puteţi redeschide bug-ul. Vă rugăm să
nu abuzaţi această facilitate. Dacă dezvoltatorul închide bug-ul
pentru a doua sau a treia oară, există şanse mari ca problema să fi
fost rezolvată.
-
RESOLVED - O decizie fermă a fost luată cum că bug-ul ar fi fost
rezolvat. De obicei bug-ul este pus în starea FIXED pentru a indica
închiderea problemei, alte decizii sunt de asemenea posibile. Despre
aceasta vom vedea mai târziu.
-
VERIFIED - Paşii prin care a trecut bug-ul sunt corecţi. Aceasta este
ceva legat de QA.
-
CLOSED - Bug-ul a fost sfârşitul valabilităţii bug-ului, care este
astfel "ingropat" între celelalte bug-uri.
Imediat apoi, găsim eroarea în strace log şi rezolvăm problema, trecând
bug-ul în starea RESOLVED FIXED şi menţionând că a fost o schimbare în
locaţia fişierelor de configurare. Un avertisment a fost introdus în
ebuild. Problema a fost rezolvată şi veţi obţine:
Figura 7.8: Bug Rezolvat |
 |
Puţin mai jos veţi observa:
Figura 7.9: Opţiuni pentru Bug |
 |
Aceasta vă permite să redeschideţi bug-ul dacă doriţi aşa ceva (de
exemplu, developer-ul crede că l-a rezolvat, însă din punctul
dumneavoastră de vedere problema persistă). Acum că a fost rezolvat,
bug-ul poate fi pus în una din următoarele stări.
-
FIXED - Bug rezolvat, folosiţi instrucţiunile pentru a rezolva problema.
-
INVALID - Nu aţi efectuat o acţiune documentată special, care a cauzat
bug-ul.
-
DUPLICATE - Nu aţi folosit corect acest ghid pentru a raporta bug-ul, şi
avem o duplicare a lui.
-
WORKSFORME - Persoana însărcinată cu rezolvarea bug-ului nu îl poate
reproduce.
-
CANTFIX - Uneori bug-ul nu poate fi rezolvat din anumite motive. Motivele
for fi documentate de persoana însărcinată cu rezolvarea problemei.
-
WONTFIX - Se aplică în general la ebuild-uri noi sau cereri de
îmbunătăţiri. Ne spune că dezvoltatorul nu vrea să adauge
acestă facilitate deoarece nu este necesară, sau există o altă
alternativă mai bună, sau nu poate fi rezolvată. Uneori puteţi
sugera o soluţie pentru rezolvarea problemei.
-
UPSTREAM - Problema nu poate fi rezolvată de echipa de dezvoltatori
Gentoo şi a fost trimisă dezvoltatoriloe care au scris original
programul. Aceştia din urmă au diferite metode de comunicare. Acesta
includ liste de discuţii, canale irc, sau chiar sisteme de raportare a
bug-urilor. Dacă nu sunteţi sigur cum să îi contactaţi, puneţi o
întrebare în bug şi cineva vă va direcţiona.
Uneori, înainte ca un bug să poată fi rezolvat, dezvoltatorul ar putea
să vă ceară să încercaţi un ebuild de test. În capitolul următor
vom vedea cum se face aceasta.
8.
Testarea Ebuild-urilor
Preluarea Fişierelor
Să presupunem că aţi raportat un bug pentru foobar2. Problema de compilare
a fost rezolvată de către dezvoltator, însă acesta ar avea nevoie de
dumneavoastră să testaţi noul ebuild pentru a se asigura că
funcţionează şi pentru dvs.:
Figura 8.1: Cerere de Testare de Ebuild |
 |
Vocabularul este puţin confuz în acest caz. Pentru început, să vedem ce
este un overlay. Un overlay este un director special precum
/usr/portage, diferenţa fiind că în momentul când rulaţi
emerge sync, fişierele conţinute în acesta nu vor fi şterse. Un
director special /usr/local/portage a fost creat în acest scop.
Continuăm prin a seta acest overlay în /etc/make.conf. Folosind
un editor de text, adăugaţi următoarea linie undeva la sfârşitul
fişierului.
Cod 8.1: Setare PORTDIR_OVERLAY |
PORTDIR_OVERLAY="/usr/local/portage"
|
Apoi, vom crea un nou director pentru acest ebuild de test. Vom pune noile
fişiere în sys-apps/foobar2. Veţi observa al doilea comentariu care ne
întreabă unde este directorul pentru acest patch. Noul director conţine
informaţia de md5sum pentru versiunea particulară a pachetului şi orice
alte fişiere care nu sunt incluse în mod normal în arhiva sursă
(patch-uri, scripturi de iniţializare, etc). Acesta este un subdirector în
pachet intitulat files. Continuaţi cu crearea acestor directoare:
Cod 8.2: Setarea Directoarelor de Categorie şi Pachet |
# mkdir -p /usr/local/portage/sys-apps/foobar2/files
|
Notă:
Opţiunea -p în comanda mkdir crează nu numai directorul files, dar şi
cele care lipsesc (sys-apps şi foobar2 în acest caz).
|
Apoi descărcăm fişierele. ebuild este pus în
/usr/local/portage/sys-apps/foobar2 iar apoi fişierul patch care
este pus în /usr/local/portage/sys-apps/foobar2/files. În
acest moment putem testa noul ebuild.
Testarea Noului Ebuild
Procesul de creare a unui ebuild care poate fi folosit de comanda emerge este
foarte simplu. Acesta poate fi creat cu comanda ebuild. Rulaţi-o după cum se
arată mai jos.
Cod 8.3: Creare fişiere Manifest şi digest md5 |
# ebuild foobar2-1.0.ebuild digest
>>> Generating digest file...
<<< foobar2-1.0.tar.bz2
>>> Generating manifest file...
<<< foobar2-1.0.ebuild
<<< files/digest-foobar2-1.0
<<< files/foobar2-1.0-Makefile.patch
>>> Computed message digests.
|
Să vedem dacă funcţionează corect.
Cod 8.4: Testare cu emerge -pv |
# emerge -pv foobar2
These are the packages that I would merge, in order:
Calculating dependencies ...done!
[ebuild N ] sys-apps/foobar2-1.0 0 kB [1]
Total size of downloads: 0 kB
Portage overlays:
[1] /usr/local/portage
|
Se pare că a mers! Veţi observa [1] lângă linia [ebuild]. Aceasta ne
îndreaptă la /usr/local/portage, care este acel overlay pe care
l-am creat anterior. Să rulăm comanda emerge.
Cod 8.5: Rezultat emerge |
# emerge foobar2
Calculating dependencies ...done!
>>> Unpacking foobar2-1.0.tar.bz2 to /var/tmp/portage/foobar2-1.0/work
* Applying foobar2-1.0-Makefile.patch ... [ ok ]
>>> Merging sys-apps/foobar2-1.0 to /
>>> chris +sandbox(preinst)
--- /usr/
--- /usr/bin/
>>> /usr/bin/foobar2
|
În prima secţiune, vedem că emerge a pornit în mod corespunzător. Din a
doua secţiune deducem că noul patch a fost aplicat fără probleme din
status-ul "[ ok ]". Noul patch funcţionează! În acest moment, putem să-l
informăm pe dezvoltator că noul patch este bun, iar acesta îl poate comite
în portage.
Concluzie
Încheiem astfel acest howto despre Bugzilla. Sperăm că îl veţi găsi
folositor. Trimiteţi-mi orice întrebare, sugestie sau comentariu referitor la
acest document pe adresa Chris White. Mulţumiri lui
moreon pentru comentariile referitoare la flag-ul -g şi erorile de compilare,
echipei #gentoo-bugs pentru ajutor cu bug-wrangling, Griffon26 pentru
comentariile despre maintainer-needed, robbat2 pentru sugestiile general şi
fox2mike pentru adăugirile şi corecturile aduse acestui document.
Conţinutul acestui document este publicat sub licenţa Creative Commons -
Attribution / Share Alike.
|