Zgłaszanie błędów w Gentoo
1.
Wprowadzenie
Przedmowa
Jeden z czynników, który opóźnia naprawienie błędu to sposób, w jaki błąd
został zgłoszony. Tworzymy ten przewodnik z myślą o usprawnieniu komunikacji
między deweloperami a użytkownikami przy poprawianiu błędów, ponieważ jest to
ważna, o ile nie najważniejsza część procesu zapewniania jakości w każdym
projekcie. Mamy nadzieję, że niniejszy przewodnik przyczyni się do jego
sukcesu.
Błędy!!!
Instalujemy pakiet lub pracujemy z programem i nagle staje się najgorsza rzecz
-- znajdujemy błąd. Jest wiele rodzajów błędów, jak na przykład awarie
instalacji za pomocą narzędzia emerge albo naruszenia ochrony pamięci (ang.
segmentation fault). Cokolwiek jest przyczyną ich wystąpienia, niewątpliwie
muszą one zostać poprawione. Oto kilka przykładów takich błędów.
Listing 1.1: Błąd podczas wykonywania |
$ ./zepsuty_kod `perl -e 'print Ax100'`
Segmentation fault
|
Listing 1.2: Awaria podczas instalacji narzędziem 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
|
Błędy te mogą być bardzo kłopotliwe. Co jednak należy zrobić gdy już na nie się
trafi? W tym rozdziale przyjrzymy się dwóm ważnym narzędziom do obsługi błędów
wykonania programu (ang. runtime error). Następnie omówimy błędy kompilacji i
jak sobie z nimi radzić. Zacznijmy jednak od pierwszego narzędzia do
"odpluskwiania" działającego kodu -- gdb
2.
Debugowanie przy pomocy GDB
Wprowadzenie
GDB, czyli (G)NU (D)e(B)ugger to narzędzie do znajdowania błędów w uruchomionym
programie, wynikających z naruszeń ochrony pamięci. Najpierw przyjrzyjmy się co
debugowanie za sobą pociąga. Jedną z podstawowych czynności jakie należy
wykonać by móc debugować program, jest zainstalowanie go narzędziem
emerge ze zmienną FEATURES="nostrip". Zapobiega to usunięciu
symboli debugowania. Dlaczego symbole te domyślnie usuwa się z programów? Powód
jest ten sam jak w przypadku kompresowania stron man programem gzip --
oszczędność miejsca. Oto jak wygląda rozmiar programu przed i po usunięciu
symboli debugowania.
Listing 2.1: Porównanie rozmiaru pliku |
-rwxr-xr-x 1 chris users 3140 6/28 13:11 zepsuty_kod
-rwxr-xr-x 1 chris users 6374 6/28 13:10 zepsuty_kod
|
Nawiasem mówiąc, program zepsuty_kod jest tym, który będziemy później
debugować za pomocą narzędzia gdb. Jak widać, program bez symboli
debugowania zajmuje 3140 bajtów, podczas gdy z nimi ma już 6374 bajty. To
prawie dwa razy więcej! Możemy zrobić jeszcze dwie rzeczy z myślą o
debugowaniu. Pierwszą z nich jest dodanie ggdb do zmiennych CFLAGS i
CXXFLAGS. Flaga ta dodaje więcej informacji przydatnych przy debugowaniu.
Wkrótce dowiemy się co z tego wynika. Oto jak może wyglądać plik
/etc/make.conf z nowo dodanymi flagami.
Listing 2.2: Ustawienia w pliku make.conf |
CFLAGS="-O1 -pipe -ggdb"
CXXFLAGS="${CFLAGS}"
|
Wreszcie, możemy dodać flagę USE debug dla danego pakietu. Dokonamy tego za
pomocą pliku package.use.
Listing 2.3: Użycie pliku package.use w celu dodania flagi debug |
# echo "kategoria/pakiet debug" >> /etc/portage/package.use
|
Uwaga:
Domyślnie katalog /etc/portage nie istnieje i możliwe, że będziemy
musieli go utworzyć, o ile jeszcze tego nie zrobiliśmy. Jeśli zaś pakiet już ma
ustawione flagi USE w pliku package.use, trzeba będzie ręcznie
zmodyfikować je za pomocą edytora tekstu.
|
Następnie ponownie instalujemy pakiet wraz z dokonanymi wyżej modyfikacjami.
Listing 2.4: Ponowna instalacja pakietu z włączonym debugowaniem |
# FEATURES="nostrip" emerge package
|
Teraz gdy symbole są już załączone, możemy przejść do debugowania programu.
Uruchamianie programu przez GDB
Załóżmy, że mamy program nazywający się "zepsuty_kod". Ktoś twierdzi, że
program ten ulega awarii i podaje jak do niej doprowadzić. Spróbujmy więc:
Listing 2.5: Usterka w programie |
$ ./zepsuty_kod `perl -e 'print Ax100'`
Segmentation fault
|
Wygląda na to, że ta osoba miała rację. Ponieważ program rzeczywiście jest
wadliwy, znaleźliśmy wspomniany błąd. Czas więc użyć gdb, by pomógł nam
rozwiązać ten problem. Najpierw uruchamiamy program gdb z parametrem
--args, podając pełną nazwę programu wraz z argumentami, jak w
przykładzie poniżej:
Listing 2.6: Uruchamianie naszego programu poprzez GDB |
$ gdb --args ./zepsuty_kod `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".
|
Uwaga:
Można także debugować przy pomocy zrzutów pamięci (ang. core dumps). Pliki te
zawierają te same informacje, które podałby program uruchomiony przez gdb.
Aby debugować program zepsuty_kod przy pomocy zrzutu pamięci, należy wykonać
polecenie gdb ./zepsuty_kod core, gdzie core to nazwa pliku ze zrzutem.
|
Powinniśmy teraz ujrzeć debugger czekający na nasze polecenia po
znaku zachęty "(gdb)". Najpierw uruchamiamy program. W tym celu należy wpisać
polecenie run, co zaowocuje informacją podobną do poniższej:
Listing 2.7: Uruchamianie programu przez GDB |
(gdb) run
Starting program: /home/chris/zepsuty_kod
Program received signal SIGSEGV, Segmentation fault.
0xb7ec6dc0 in strcpy () from /lib/libc.so.6
|
Widzimy tu uruchamianie programu, a także powiadomienie go o sygnale SIGSEGV,
czyli naruszeniu ochrony pamięci. W ten sposób GDB przekazuje nam, że program
uległ awarii. Dostajemy także informację o ostatniej funkcji, jaką można było
wyśledzić, zanim program zakończył działanie. Niestety, niekoniecznie będzie to
użyteczna informacja, ponieważ w programie może być wiele funkcji strcpy, co
utrudni deweloperom odnalezienie tej, w której rzeczywiście wystąpił błąd. Aby
im w tym pomóc, dokonujemy śledzenia wstecznego (ang. backtrace). Za pomocą
tej operacji poruszamy się do tyłu poprzez wszystkie funkcje, które zostały
wywołane w trakcie pracy programu, aż do tej, w której wystąpił błąd. Funkcje,
które zwracają wynik (i nie powodują awarii programu) nie pojawią się. Aby
dokonać śledzenia wstecznego należy wpisać w gdb polecenie bt. Otrzymamy
wynik zbliżony do tego:
Listing 2.8: Backtrace programu |
(gdb) bt
#0 0xb7ec6dc0 in strcpy () from /lib/libc.so.6
#1 0x0804838c in run_it ()
#2 0x080483ba in main ()
|
Teraz łatwo zobaczyć co się dzieje. Najpierw wywoływana jest funkcja main(),
następnie run_it(), a gdzieś wewnątrz run_it() nasz winowajca, czyli funkcja
strcpy(). To właśnie w ten sposób można zawęzić listę możliwych przyczyn błędu.
Należy zwrócić jednak uwagę na kilka rzeczy. Po pierwsze, jeśli zapomnimy o
włączeniu symboli debugowania za pomocą FEATURES="nostrip", gdb wypisze
nam coś takiego:
Listing 2.9: Śledzenie wsteczne programu bez symboli debugowania |
(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 ?? ()
|
Powyższe wyjście zawiera wiele podwójnych znaków zapytania. Dzieje się tak,
ponieważ bez symboli debugowania gdb nie wie jak program był wykonywany.
Dlatego tak bardzo ważne jest, aby ich nie usuwać. Przypomnijmy o
niedawno wspomnianej fladze -ggdb. Zobaczmy co wypisze gdb, jeśli ją włączymy:
Listing 2.10: Śledzenie wsteczne programu z flagą -ggdb |
(gdb) bt
#0 0xb7e4bdc0 in strcpy () from /lib/libc.so.6
#1 0x0804838c in run_it (input=0x0) at zepsuty_kod.c:7
#2 0x080483ba in main (argc=1, argv=0xbfd3a434) at zepsuty_kod.c:12
|
Na powyższym przykładzie widać o ile więcej informacji dostępnych jest dla
deweloperów. Wyświetlane są nie tylko informacje o funkcjach, ale także numery
linii plików źródłowych. Jeśli jesteśmy sobie w stanie pozwolić na zużycie
większej ilości miejsca na dysku przez program, jest to zdecydowanie najlepszy
sposób debugowania. Oto jak zmienia się rozmiar pliku binarnego w zależności
od sposobu kompilacji.
Listing 2.11: Różnice w rozmiarze z flagą -ggdb |
-rwxr-xr-x 1 chris users 3140 6/28 13:11 zepsuty_kod
-rwxr-xr-x 1 chris users 6374 6/28 13:10 zepsuty_kod
-rwxr-xr-x 1 chris users 19552 6/28 13:11 zepsuty_kod
|
Jak widać, włączenie flagi -ggdb dodaje około 13178 bajtów do rozmiaru
pliku w stosunku do pliku, w którym włączone są jedynie symbole debugowania.
Jednakże, jak pokazaliśmy powyżej, ten przyrost rozmiaru jest usprawiedliwiony,
jeśli chcemy pokazać efekty debugowania deweloperom. Wynik śledzenia wstecznego
może być zapisany do pliku poprzez skopiowanie i wklejenie z terminala (możemy
użyć gpm, jeśli nie korzystamy z terminala X. Informacje, jak wklejać za pomocą
gpm, znajdują się w jego
dokumentacji). Zakończyliśmy już pracę z gdb, możemy zatem z niego
wyjść.
Listing 2.12: Wyjście z GDB |
(gdb) quit
The program is running. Exit anyway? (y or n) y
$
|
Tym sposobem zakończyliśmy nasz krótki kurs korzystania z narzędzia gdb.
Mamy nadzieję, że dzięki niemu powstaną lepsze raporty o błędach. Istnieją
jednak inne typy błędów, które mogą spowodować awarię programu w trakcie jego
działania. Może się to stać na przykład na skutek niewłaściwego odwoływania się
do pliku. Takie błędy odnajdziemy przy pomocy narzędzia o nazwie strace.
3.
Wykrywanie błędów w dostępie do plików przy pomocy narzędzia strace
Wprowadzenie
Programy często korzystają z plików w celu odczytywania konfiguracji, uzyskania
dostępu do sprzętu lub zapisywania logów. Czasem program próbuje odwołać się do
takich plików w niewłaściwy sposób. Narzędzie o nazwie strace stworzono
właśnie po to, by radzić sobie z takimi błędami. Śledzi ono wywołania systemowe
(ang. to trace -- śledzić, tropić -- stąd nazwa), a więc odwołania do pamięci i
plików. W ramach przykładu użyjemy programu foobar2, który jest nowszą wersją
programu foobar. Jednakże po przesiadce na foobar2 zauważamy brak naszej
konfiguracji! W pierwszej wersji programu ustawiliśmy go tak aby wypisywał
napis "foo", jednak teraz wypisuje domyślne "bar".
Listing 3.1: Program foobar2 z niewłaściwą konfiguracją |
$ ./foobar2
Konfiguracja: bar
|
W poprzedniej konfiguracji ta sama opcja miała wartość "foo", użyjmy więc
narzędzia strace aby dowiedzieć się, co się stało.
Zastosowanie programu strace do znalezienia błędu
Chcemy, aby strace wypisał rezultaty wywołań systemowych. Uruchamiamy
więc program strace z parametrem -o[plik]. Wypróbujmy to na programie
foobar2.
Listing 3.2: Uruchamianie foobar2 poprzez strace |
# strace -ostrace.log ./foobar2
|
Utworzy to plik strace.log w bieżącym katalogu. Poniżej znajdują
się najistotniejsze dla nas wiersze tego pliku.
Listing 3.3: Fragment pliku logowania za pomocą strace |
open(".foobar2/config", O_RDONLY) = 3
read(3, "bar", 3) = 3
|
Więc w tym tkwi problem. Ktoś zmienił ścieżkę konfiguracji z
.foobar na .foobar2. Widzimy także, że program
poprawnie wczytuje "bar" z pliku. W tym przypadku najlepiej powiadomić osobę
odpowiedzialną za plik ebuild, aby dodała ostrzeżenie o tej zmianie. Jednak na
razie możemy skopiować plik konfiguracyjny z katalogu .foobar we
właściwe miejsce.
Podsumowanie
W ten sposób zakończyliśmy temat błędów pojawiających się w czasie działania
programu. Jednak, pomimo iż błędy te przysparzają wielu problemów, będą one
naszym ostatnim zmartwieniem, gdy program nie będzie się nawet kompilował.
Przyjrzyjmy się więc jak można poradzić sobie z błędami kompilacji w czasie
używania narzędzia emerge.
4.
Jak radzić sobie z błędami instalacji
Wprowadzenie
Błędy przy instalacji za pomocą emerge takie jak ten, który pokazaliśmy
na początku, mogą być przyczyną frustracji użytkowników. Zgłaszanie ich jest
uznawane za jeden z najważniejszych sposobów wspierania Gentoo. Przyjrzyjmy się
zatem przykładowemu procesowi instalacji programu foobar2, w czasie którego
wystąpią błędy kompilacji.
Analiza błędów instalacji
Zwróćmy uwagę na ten prosty błąd podczas korzystania z polecenia emerge:
Listing 4.1: Błąd podczas instalacji (dłuższe linie zostały zawinięte) |
gcc -D__TEST__ -D__GNU__ -D__LINUX__ -L/usr/lib -I/usr/include -L/usr/laib/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
|
Program kompilował się bezproblemowo, aż tu nagle wyświetla nam komunikat
błędu. Komunikat ten możemy podzielić na trzy części, opisane poniżej:
komunikaty kompilatora, błąd budowania i komunikat błędu emerge.
Listing 4.2: Części błędu (dłuższe linie zostały zawinięte) |
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
|
Komunikaty kompilatora poprzedzają wystąpienie błędu. Najczęściej warto
dołączyć przynajmniej 10 ostatnich linii informacji o kompilacji aby deweloper
wiedział, w którym momencie tego procesu wystąpił błąd.
Nie ważne jaki język mamy ustawiony w systemie, błędy kompilacji umieszczamy
zawsze w wersji anglojęzycznej. Możemy przełączyć wyświetlanie angielskich
wersji ostrzeżeń poprzez dodanie zmiennej LC_ALL=C do polecenia emerge:
Listing 4.3: Czasowe przełączanie lokali na języki angielski |
# LC_ALL=C emerge sys-apps/foobar2
|
Uwaga:
Jest to jedyna sytuacja, w której dopuszcza się użycie zmiennej środowiskowej
LC_ALL do zmiany ustawień języka systemu. W przypadku gdy chcemy na
stałe zmienić lokalizację należy odnieść się do podręcznika Lokalizacja Gentoo Linux.
|
Błędy w działaniu narzędzia make to te właściwe i również tej informacji
potrzebuje deweloper. Widząc napis "make: ***" najczęściej możemy poznać
miejsce wystąpienia błędu. Zwykle wystarczy, że skopiujemy 10 linijek powyżej
tego miejsca, a deweloper poradzi sobie z naprawieniem problemu. Czasem jednak
okazuje się, że to za mało i wkrótce przyjrzymy się innym możliwościom.
Ostatni komunikat jest błędem zgłaszanym przez emerge. Czasami również i
on zawiera przydatne informacje, jednak często się zdarza, że zgłaszany jest
wyłącznie ten mało istotny komunikat. Dopiero dysponując też komunikatem błędu
make i komunikatami kompilatora deweloper może wywnioskować, jaka aplikacja i
która wersja pakietu jest wadliwa. Na marginesie, make jest najczęściej
używanym narzędziem do budowania programów, jednak nie jedynym. Jeśli
nie widać nigdzie komunikatu "make: ***", trzeba po prostu przekopiować 20
linijek przed komunikatem emerge. Powinno to wystarczyć w przypadku większości
komunikatów o błędach instalacji. Jeśli jednak jest ich bardzo wiele, 10 linii
może nie objąć wszystkiego. Wówczas warto zainteresować się zmienną
PORT_LOGDIR.
Program emerge i zmienna PORT_LOGDIR
PORT_LOGDIR to zmienna systemu portage, która definiuje katalog z logami
narzędzia emerge. Najpierw spróbujmy uruchomić proces instalacji ze zmienną
PORT_LOGDIR ustawioną na nasz ulubiony katalog z logami. Załóżmy, że istnieje
katalog /var/log/portage. Użyjemy go jako miejsca na logi:
Uwaga:
Domyślnie katalog /var/log/portage nie istnieje i należy utworzyć
go ręcznie. Jeśli tego nie zrobimy, portage nie zapisze logów.
|
Listing 4.4: Instalowanie ze zmienną PORT_LOGDIR |
# PORT_LOGDIR=/var/log/portage emerge cate-gory/foobar2
|
Oczywiście proces znowu kończy się niepowodzeniem, tym razem jednak mamy log,
który możemy potem dołączyć do raportu błędu. Zajrzyjmy do katalogu.
Listing 4.5: Zawartość katalogu zdefiniowanego przez 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 cate-gory:foobar2-1.0:20090110-213217.log
|
Pliki logów mają nazwę [licznik]:[nazwa-pakietu]-[wersja]:[data].log. Szybki
rzutem oka na plik log prześledzimy cały proces instalacji. Później dowiemy się
jak dołączyć go przy zgłaszaniu błędu. Skoro mamy już informacje potrzebne do
zgłoszenia błędu, możemy to zrobić. Najpierw musimy się jednak upewnić, czy
nikt nie zgłosił już tego problemu przed nami. Przyjrzyjmy się więc
przeszukiwaniu raportów o błędach.
5.
Przeszukiwanie Bugzilli
Wprowadzenie
W projekcie Gentoo używamy systemu Bugzilla do zgłaszania błędów. Nasza
Bugzilla dostępna jest przez protokoły HTTPS i HTTP. HTTPS dostępne jest
głównie dla osób korzystających z niezabezpieczonych sieci. W następnych
przykładach będziemy używać właśnie tej wersji. Zajrzyjmy teraz na stronę Gentoo Bugs aby się z nią zapoznać.
Jedną z najbardziej frustrujących deweloperów rzeczy jest otrzymywanie
powtórnych raportów o błędach. Zabierają one cenny czas, który mogliby
poświęcić pracy nad poważniejszymi błędami. Z reguły zgłaszaniu wielokrotnie
tych samych błędów można łatwo zapobiec. Przyjrzymy się więc kwestii
wyszukania błędów i stwierdzenia, że jest zbliżony do naszego. W ramach
przykładu wykorzystamy użyty już wcześniej błąd w czasie instalowania programu
xclass.
Listing 5.1: Błąd w przy instalacji 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
|
Aby rozpocząć poszukiwania, musimy udać się na stronę główną Bugzilli.
Ilustracja 5.1: Strona główna Bugzilli |
 |
Kliknijmy na odnośnik "Query Existing bug reports" (przeszukaj istniejące
raporty błędów). Wybieramy tę opcję zamiast podstawowej funkcji wyszukiwania,
ponieważ ta druga daje zbyt ogólne wyniki utrudniając przeszukiwanie rezultatów
i zauważenie zduplikowanego błędu. Po kliknięciu na odnośnik dotrzemy do
następnej strony:
Ilustracja 5.2: Strona przeszukiwania Bugzilli |
 |
Uwaga:
Jeśli kiedykolwiek wcześniej używaliśmy opcji Advanced Search (zaawansowanego
wyszukiwania), najprawdopodobniej to właśnie ją ujrzymy.
|
Przejdźmy dalej, klikając na odnośnik "Advanced Search" aby wejść na stronę
zaawansowanego wyszukiwania.
Ilustracja 5.3: Strona zaawansowanego wyszukiwania |
 |
Tak wygląda strona Advanced Search. Na pierwszy rzut oka może wyglądać nieco
przytłaczająco, więc przyjrzymy się jedynie kilku prostym obszarom by zawęzić
zbyt ogólne wyniki wyszukiwania zwykle zwracane przez Bugzillę.
Ilustracja 5.4: Zawartość |
 |
Pierwsze pole to podsumowanie raportu błędu. Wpiszemy tu po prostu nazwę
pakietu, który uległ awarii. Jeśli nie otrzymamy wyników, spróbujmy usunąć
nazwę pakietu na wypadek, gdyby ktoś nie podał jej w podsumowaniu (mało
prawdopodobne, ale widzieliśmy już wiele dziwnych raportów o błędach).
W polach Product (produkt), Component (składnik) i Version (wersja) powinniśmy
pozostawić wartości domyślne. Unikniemy w ten sposób nadmiernego zawężenia
obszaru poszukiwań i pominięcia interesujących nas raportów.
Pole Comment (komentarz) jest najważniejsze. Przy jego pomocy podamy to, co
wygląda na charakterystyczne dla danego błędu. Generalnie nie należy wpisywać
rzeczy takich jak początku komunikatu o błędzie budowania. Trzeba odnaleźć
linię wcześniej, która mówi o prawdziwym błędzie. Musimy także odfiltrować
znaki interpunkcyjne, inaczej Bugzilla może zinterpretować komentarz w inny
sposób, niż byśmy tego sobie życzyli. Oto przykład z naszego błędu instalowania
programu xclass:
Listing 5.2: Zawartość pola komentarza |
menudef.h:78: error: brace-enclosed initializer used to initialize `OXPopupMenu'
menudef.h 78 error brace-enclosed initializer used to initialize OXPopupMenu
|
Powyższy wpis jest wystarczająco precyzyjny, aby nie musieć przebijać się przez
możliwe inne błędy kompilacji programu xclass.
Pola URI, Whiteboard i Keywords możemy zostawić w spokoju. To, co do tej pory
wpisaliśmy, powinno wystarczyć. Przyjrzyjmy się wprowadzonym danym.
Ilustracja 5.5: Gotowy formularz wyszukiwania |
 |
Kliknijmy więc na przycisku Search (szukaj) aby otrzymać wyniki...
Ilustracja 5.6: Wyniki wyszukiwania |
 |
Tylko 2 raporty! Znacznie łatwiej z tyloma dać sobie rady. Kliknijmy na
pierwszy z nich. Okazuje się, że właśnie tego szukaliśmy.
Ilustracja 5.7: Bug znaleziony |
 |
Nie tylko o ten raport nam chodziło, ale na dodatek problem został już
rozwiązany. Czytając ostatni komentarz dowiemy się w jaki sposób i czy coś
sami musimy zrobić. Zobaczmy zatem co by było, gdybyśmy nie użyli opcji
zaawansowanego szukania.
Ilustracja 5.8: Wyniki prostego szukania |
 |
Musielibyśmy przyjrzeć się kolejnym czterem raportom! W przypadku dużych
pakietów jest jeszcze gorzej. Lecz stosując omówionych wcześniej opcje możemy
znacznie zawęzić wyniki wyszukiwania i znaleźć konkretny raport.
Podsumowanie
Załóżmy, że szukaliśmy na wszystkie możliwe sposoby, ale nie znaleźliśmy już
istniejącego raportu. Wykryliśmy zatem nowy błąd. Przyjrzyjmy się więc
procesowi zgłaszania błędów.
6.
Raportowanie błędów
Wprowadzenie
W tym rozdziale dowiemy się jak za pomocą Bugzilli zgłosić nowy błąd. Przejdźmy
na stronę Gentoo Bugs.
Ilustracja 6.1: Strona główna Bugzilli |
 |
Kliknijmy na odnośniku "Report a Bug -- Using the guided format" (Zgłoś błąd --
krok po kroku)
Ilustracja 6.2: Wybór produktu |
 |
Jak widać, położono duży nacisk na to aby raport został poprawnie
przydzielony. Większość usterek trafia do grupy "Gentoo Linux".
Pomimo tego, niektórzy zgłaszają błędy dotyczące ebuildów do kategorii "portage
development" (zakładając, że zespół odpowiedzialny za portage zajmuje się
również drzewem pakietów) lub infra (sądząc, że ten, kto odpowiada za
infrastrukturę ma dostęp do serwerów lustrzanych i rsync i może bezpośrednio
poprawić błąd). Tak jednak nie należy.
Często tego rodzaju nieporozumienia dotyczą też błędów w dokumentacji. Załóżmy,
że użytkownik znajduje błąd w dokumentacji Catalyst. Zwykle zgłoszenie
przypisywane jest do Docs-user, gdzie zostanie przydzielony do GDP, podczas gdy w rzeczywistości powinno
trafić do któregoś z członków zespołu Release
Engineering. Generalnie należy przyjąć, że dokumentacja znajdująca się w
podkatalogach http://www.gentoo.org/doc/* powinna trafić do GDP,
zaś teksty z http://www.gentoo.org/proj/* trafiają każdy do
swojego macierzystego zespołu.
Uwaga:
Korzystniejsze będzie przydzielenie zgłoszonego błędu do produktu Gentoo Linux
pomimo że powinien trafić gdzie indziej, niż żeby błąd kategorii Gentoo Linux
trafił do innej. Oczywiście wolelibyśmy, aby raporty były przydzielane
poprawnie, jednak z dwojga złego pierwsza opcja jest milej widziana i bardziej
zrozumiała (z wyjątkiem błędów dotyczących strony WWW... tu mielibyśmy
problem).
|
Nasz problem dotyczy pliku ebuild, trafia więc do produktu Gentoo Linux. Tam
też kierujemy nasze kroki, gdzie zostaje nam przedstawiony składający się z
kilku kroków proces zgłaszania błędu.
Ilustracja 6.3: Formularz w stylu przewodnika, krok pierwszy |
 |
Czerwony napis sugeruje, że pierwszy krok jest bardzo istotny. To w tym kroku
szukamy czy ktoś nie natknął się na ten sam błąd co my i już go nie zgłosił.
Jeśli opuścilibyśmy ten krok a raport taki jak nasz już istnieje, nasz zostanie
oznaczony flagą DUPLICATE (duplikat) i zmarnuje tylko czas ludziom zajmującym
się kontrolą jakości. Przekreślone numery u góry to właśnie duplikaty błędów.
Przejdźmy do kroku drugiego, w którym podajemy informacje.
Wymagane dane
Ilustracja 6.4: Podstawowe dane |
 |
Przyjrzyjmy się im bliżej.
-
Po pierwsze, Product. Pole to ustali przynależność raportu do określonej
części Gentoo, takiej jak Bugzilla (błędy dotyczące bugs.gentoo.org),
Docs-user (dokumentacja użytkownika) lub Gentoo Linux (pliki ebuild i tym
podobne).
-
W polu Component określamy gdzie dokładnie występuje problem, a właściwie w
której części wybranego produktu. To ułatwia klasyfikację.
-
W polu Hardware platform (platforma sprzętowa) informujemy, na jakiej
pracujemy architekturze. Na przykład jeśli nasz sprzęt to SPARC, to właśnie
tak ustawiamy to pole.
-
W polu Operating System wpisujemy, jakiego systemu operacyjnego używamy.
Gentoo jest nazywane "meta-dystrybucją", a więc obejmuje również inne
systemy operacyjne niż Linux.
Tak więc dla naszego przykładowego raportu podajemy:
- Product - Gentoo Linux (Ponieważ problem dotyczy pliku ebuild)
-
Component - Application [aplikacja] (Błąd występuje w aplikacji foobar2)
- Hardware Platform - All [wszystkie] (Ten błąd może wystąpić na
którejkolwiek z architektur)
- Operating System - All [wszystkie] (Może dotyczyć każdego systemu)
Ilustracja 6.5: Podstawowe dane wypełnione |
 |
-
Pole Build Identifier (identyfikator) to po prostu stała napisowa User
Agent przeglądarki internetowej, za pomocą której zgłaszany jest błąd (w
celach logowania). Możemy pozostawić to pole bez zmian.
-
URL jest dodatkowym polem, którego używamy do wskazywania informacji z
innych stron (np. Bugzilla producenta oprogramowania, notatki wydania na
stronie domowej itd.). Nigdy nie powinniśmy używać pola URL do wpisywania
linków do stron typu pastebin z wiadomościami błędów, logami czy wynikiem
polecenia emerge --info itd. Tego typu informacje należy umieszczać
już w treści raportu.
-
W polu Summary (podsumowanie) powinniśmy podać kategorię pakietu, jego
nazwę i numer wersji.
Pominięcie kategorii w podsumowaniu nie jest dużym błędem, warto jednak o niej
pamiętać. Koniecznie trzeba jednak podać nazwę pakietu, inaczej nikt nie będzie
wiedział w czym tak naprawdę zgłaszamy błąd i będzie musiał nas później o to
spytać. Numer wersji jest ważny dla ludzi przeszukujących raporty. Gdyby 20
osób zgłosiło błędy i nikt nie zamieścił numeru wersji, ludzie wyszukujący
podobne raporty nie wiedzieliby, który ich dotyczy. Jeśli raportów byłoby 200,
przejrzenie ich nie byłoby proste... Na koniec dobrze będzie umieścić krótki
opis awarii. Oto przykład:
Ilustracja 6.6: Podsumowanie |
 |
Tych kilka prostych zasad znacznie ułatwi obsługę raportów. Teraz zajmiemy się
polem Details (szczegóły), gdzie podajemy informację o błędzie. Zademonstrujemy
to na przykładzie:
Ilustracja 6.7: Szczegóły |
 |
Teraz deweloper będzie wiedział dlaczego zgłosiliśmy błąd. Może wówczas
spróbować sprawdzić czy błąd zachodzi u niego. Pole Reproducibility
(powtarzalność) mówi, jak często byliśmy w stanie sprawić, by problem wystąpił.
W naszym przykładzie problem powtarza się za każdym uruchomieniem programu
foobar2. Napiszmy więc o tym.
Ilustracja 6.8: Powtarzalność |
 |
Wyjaśniliśmy w jaki sposób natknęliśmy się na błąd. Następnym krokiem jest
opisanie w polu Results (wyniki) jaki był rezultat uruchomienia, a jaki efekt
był naszym zamiarem.
Ilustracja 6.9: Wyniki |
 |
Następnie powinniśmy podać w polu Additional information (dodatkowe informacje)
np. wyniki śledzenia stosu (ang. stack traces), fragmenty logów programu
strace (ponieważ całe logi zwykle są obszerne i przez to nieprzydatne).
Koniecznie należy załączyć wynik polecenia emerge --info. Oto przykład:
Ilustracja 6.10: Dodatkowe informacje |
 |
W końcu wybieramy wagę błędu w polu Severity. Należy to rozpatrzyć ze
szczególną uwagą. W większości przypadków można pozostawić tę opcję w spokoju,
a ktoś podniesie albo opuści wagę za nas. Jeśli jednak chcemy zrobić to sami,
należy dokładnie zapoznać się z poniższą listą i upewnić się, że nie popełniamy
błędu. Oto poszczególne poziomy ważności.
-
Blocker (blokujący) - program po prostu nie chce się zainstalować lub
znacznie zakłóca działanie systemu. Na przykład problem z
baselayout, który uniemożliwiałby uruchomienie systemu, byłby pewnym
kandydatem do nadania mu miana blokującego.
-
Critical (krytyczny) - program traci dane lub przejawia wyciek pamięci
(ang. memory leak). Problem z ważnym programem, jak na przykład
net-tools, który nie daje się skompilować, może być oznaczony jako
krytyczny. Nie uniemożliwia to uruchomienia systemu, ale znacznie utrudnia
jego normalne funkcjonowanie.
-
Major (ważny) - Program ulega awarii, ale nie dzieje się nic, co poważnie
uszkadza system lub powoduje utratę danych.
-
Minor (mało ważny) - Program przejawia problemy od czasu do czasu, można
tego jednak czasem uniknąć.
-
Normal (normalny) - Opcja domyślna. Jeśli nie jesteśmy pewni, należy
pozostawić właśnie to ustawienie, chyba że mamy do czynienia z nowym
programem albo zmiana jest kosmetyczna. W takim przypadku niżej znajdziemy
lepszą opcję.
-
Trivial (trywialny) - mało istotne rzeczy typu literówek albo poprawek
białych znaków.
-
Enhancement (udoskonalenie) - Prośba o dołączenie nowej funkcji programu, a
w szczególności o nowe ebuildy.
Ilustracja 6.11: Waga |
 |
W naszym przypadku pozostajemy przy domyślnej opcji Normal.
Możemy teraz zgłosić błąd klikając przycisk Submit Bug Report (wyślij raport o
błędzie). Po chwili ukaże się on na ekranie. Rezultat możemy obejrzeć jako Bug 97561. Zobaczmy
jak zostanie obsłużony.
Natychmiastowe prośby o aktualizację pakietów
Jak dotąd opisywaliśmy sposób postępowania przy zgłaszaniu usterek. Wspomnimy
teraz o rzeczach, których nie należy robić.
Załóżmy, że niecierpliwie obserwowałeś kalendarium wydań danego programu i
okazuje się, że kilka minut temu została wydana jego nowa wersja. Niektórzy
natychmiast popędziliby by powiadomić o nowej wersji na Bugzilli informacją
typu: należy podnieść numer wersji (version bump), dodać program do drzewa
Portage, itp. Jednak właśnie tak nie powinno się postępować. Tego typu
żądania zwane są prośbami o natychmiastową aktualizację (zero-day/0-day bump
requests), gdyż są wysyłane dnia wydania danej wersji.
Ważne:
Należy poczekać przynajmniej 48 godzin przed informowaniem na Bugzilli
o nowej wersji programu. Koniecznie trzeba sprawdzić czy ktoś już
nie zawiadomił o niej lub czy deweloperzy Gentoo już się nią nie zajęli.
|
Dlaczego trzeba poczekać? Po pierwsze, nietaktownym jest wymagać od deweloperów
Gentoo, by rzucili wszystko nad czym pracują, aby tylko dodać nową wersję
programu, która wyszła 15 minut temu. Żądanie natychmiastowej aktualizacji może
zostać oznaczone jako INVALID (nieprawidłowe) lub LATER (później), gdyż
deweloperzy mają dosyć ważniejszych problemów do rozwiązania. Po drugie, z
reguły wiedzą o zbliżających się terminach wydania nowych wersji programów dużo
wcześniej niż ich użytkownicy, ponieważ muszą śledzić działania deweloperów
rzeczonego programu. W wielu przypadkach na Bugzilli podali już informację, a
nawet dodali pakiet do drzewa Portage jako zamaskowany.
Wykaż się inteligencją testując i prosząc o nowe wersje pakietów. Sprawdź, czy
żądanie jest już rozpatrywane czy niedawno zaktualizowałeś swoje drzewo
Portage czy program w rzeczywistości został oficjalnie wydany przez jego
twórców. Podążanie za poczuciem zdrowego rozsądku jest mile widziane przez
deweloperów, którzy nawet bez niepotrzebnej pracy mają dużo do zrobienia.
Jeśli minęło kilka dni od daty wydania i jesteś pewien, że żadne prośby o
aktualizację nie zostały zamieszczone na Bugzilli oraz, że programu nie ma w
drzewie Portage, wtedy powiadom o nowej wersji. Nie zapomnij wspomnieć o tym,
że program poprawnie kompiluje się i działa na twojej architekturze. Wszelkie
pomocne informacje są bardzo mile widziane.
Chcesz zobaczyć najnowszą wersję swojego ulubionego pakietu w drzewie Portage?
Raportuj z głową.
7.
Prace nad zgłoszonymi problemami
Oglądając zawartość raportu o błędzie zauważamy, że został on przydzielony do
bug-wranglers@gentoo.org. Jest to domyślny adres dla raportów dotyczących
składnika Application.
Ilustracja 7.1: Podstawowe informacje o nowym zgłoszeniu |
 |
Dostępne są także szczegółowe informacje, które podaliśmy.
Ilustracja 7.2: Szczegółowe informacje z raportu o błędzie |
 |
Jednakże bug-wranglers (zwykle) nie zajmują się naprawianiem błędów,
przydzielimy więc zgłoszenie komuś, kto to zrobi (możemy też pozwolić grupie
bug-wranglers przydzielić go za nas). W tym celu skorzystamy z pliku
metadata.xml danego pakietu. Zwykle można go znaleźć na ścieżce zbliżonej do
tej: /usr/portage/kategoria/pakiet/metadata.xml. Oto plik, który
przygotowałem dla programu foobar2.
Uwaga:
Zmieniać przydział raportu może osoba, która dany problem zgłosiła bądź też
jest członkiem odpowiedniej grupy Bugzilli Gentoo -- na przykład Gentoo
Developers (deweloperzy Gentoo).
|
Listing 7.1: Przykładowy plik 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>
|
Zwróćmy uwagę na sekcję maintainer (opiekun). W niej wyszczególniony jest
opiekun pakietu, którym w tym przypadku jest autor niniejszego tekstu, Chris
White. Jego adres email to chriswhite@gentoo.org. Użyjemy go do zmiany
przydziału zgłoszenia, klikając na przełącznik obok Reassign bug to (przydziel
raport) i podając adres email opiekuna.
Uwaga:
Jeśli pakiet nie posiada pliku metadata.xml, powinniśmy zmienić przydział na
maintainer-needed@gentoo.org, zaś dla pakietu, która potrzebuje dewelopera
Gentoo jako opiekuna odpowiednim przydziałem będzie
maintainer-wanted@gentoo.org
|
Ilustracja 7.3: Zmiana przydziału raportu |
 |
Kliknijmy teraz przycisk Commit (wyślij), aby zatwierdzić zmiany. Raport został
przydzielony do mnie (autora tekstu). Niedługo później zostaniemy powiadomieni
(zwykle przez email), że odpowiedziałem na zgłoszenie. Napisałem, że chciałbym
obejrzeć plik logowania od strace aby dowiedzieć się, jak program próbuje
dotrzeć do pliku konfiguracyjnego. Użyjemy wcześniej podanych instrukcji w
celu skorzystania z programu strace i wygenerowania pliku logowania. Następnie
należy dołączyć go do raportu. Aby to zrobić, trzeba kliknąć odnośnik Create A
New Attachment (dodaj załącznik).
Ilustracja 7.4: Nowy załącznik |
 |
Chcemy teraz dołączyć plik logowania. Opiszemy procedurę krok po kroku.
-
File (plik) - tu podajemy położenie załączanego pliku
strace.log. Możemy użyć przycisku Browse... (przeglądaj) aby
wybrać plik za pomocą okna dialogowego, ewentualnie wpisać ścieżkę ręcznie
w polu tekstowym.
-
Description (opis) - kilka słów opisujących załącznik. Wpiszmy tu po prostu
strace.log, co będzie oczywiste.
-
Content Type (typ zawartości) - rodzaj pliku, który dołączamy do raportu.
-
Obsoletes (unieważnia) - jeśli do raportu zostały wcześniej dołączone
jakieś załączniki, mamy możliwość zaznaczenia, że nasz załącznik ma je
unieważnić. Nasze zgłoszenie nie zawiera żadnych innych załączników, więc
nie zmieniamy tej opcji.
-
Comment (komentarz) - tu możemy dopisać komentarz, który będzie widoczny
obok załącznika. Jeśli zaistniałaby taka potrzeba, można dokładnie omówić
załączany plik.
Jeszcze kilka szczegółów na temat pola Content Type. Możemy zaznaczyć pole
patch, jeśli dołączamy łatkę. Możemy też zaznaczyć auto-detect (automatyczne
wykrywanie), aby Bugzilla sama próbowała wykryć typ pliku (niewskazane). Inne
możliwości to Select from list (wybierz z listy), wybór z listy najczęściej
spotykanych typów plików. Do większości załączników używa się typu
text/plain (czysty tekst). Inne to image/gif, image/jpeg lub image/png dla
obrazków (w zależności od formatu) i application/octet-stream dla plików
skompresowanych, jak na przykład .tar.bz2.
Ilustracja 7.5: Dodano nowy załącznik |
 |
Dołączyliśmy plik strace.log i teraz widać go w naszym raporcie.
Ilustracja 7.6: Dołączony plik logowania przez strace |
 |
Wspomnieliśmy wcześniej, że czasem po wystąpieniu błędu procesu instalacji
zostaniemy poproszeni o dołączenie pliku do zgłaszanego błędu. Poniżej
zamieszczono przykład.
Listing 7.2: Przykładowa prośba o dołączenie pliku |
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.
|
Powinniśmy dołączyć każdy taki plik zgłaszając błąd.
Czasami deweloper może poprosić o dołączenie diffa (pliku porównawczego) lub
łatki.
Listing 7.3: Utworzenie pliku diff |
$ cp file file.old
$ nano file
$ diff -u file.old file
|
Dla plików ze źródłami języka C/C++ dodaje się opcję -p, aby pokazać
jakiej funkcji dotyczy każda ze zmian:
Listing 7.4: Tworzenie diffa kodu źródłowego w C/C++ |
$ cp file.c file.c.old
$ nano file.c
$ diff -up file.c.old file.c
|
GDP (deweloperzy dokumentacji) wymagają korzystania z opcji -Nt jak
również -u. Ma to głównie znaczenie przy wcięciach. Tworzenie takiego
diffa wygląda następująco:
Listing 7.5: Tworzenie diffu dokumentacji |
$ cp file.xml file.xml.old
$ nano file.xml
$ diff -Nut file.xml.old file.xml
|
Załóżmy, że kiedy zrobiliśmy już to wszystko, ktoś inny znajduje nasz raport
szukając w Bugzilli i z ciekawości chciałby wiedzieć, co się dalej z tym
zgłoszeniem stanie. Może zrobić to podając swój adres email w polu Add CC
(wysyłaj kopie wiadomości), tak jak pokazano poniżej.
Ilustracja 7.7: Dodawanie adresu email do listy |
 |
Uwaga:
Adresy email muszą być zarejestrowane w Bugzilli Gentoo. Aby dodać kilka
adresów, należy rozdzielić je przecinkami lub spacjami.
|
Po wykonaniu całej tej pracy, nasz raport może uzyskać rozmaite oznaczenia
stanu. Zwykle robią to deweloperzy Gentoo, lecz czasem również zgłaszający.
Poniżej znajdziemy różne możliwe stany, które raport może przyjąć.
-
UNCONFIRMED (niepotwierdzony) - jest to raczej rzadko spotykany stan.
Oznacza on, że zgłaszający zgłosił usterkę używając zaawansowanej metody i
nie jest pewny czy to rzeczywiście prawdziwy błąd.
- NEW (nowy) - w ten sposób oznaczane są raporty zaraz po utworzeniu.
-
ASSIGNED (przydzielony) - jeśli osoba, której przydzieliliśmy zgłoszenie,
potwierdzi je, najczęściej zmieni jego stan na ASSIGNED jako oznakę pracy
nad nim. Możemy po tym poznać, że nasz raport został uznany za opisujący
trudny problem.
-
REOPENED (otwarty ponownie) - ktoś zamknął już raport, ale uznaliśmy
rozwiązanie za nie do końca właściwe lub problem wciąż istnieje. W tym
momencie możemy otworzyć raport ponownie. Prosimy tego nie
nadużywać. Jeśli deweloper zamknie zgłoszenie po raz drugi lub trzeci,
najprawdopodobniej raport powinien być zamknięty.
-
RESOLVED (rozwiązany) - została podjęta ostateczna decyzja w sprawie
zgłoszenia. Najczęściej uzyskuje ono również status FIXED (naprawiony)
wskazujący, że znaleziono rozwiązanie. Możliwe są również inne oznaczenia
statusu, omówione poniżej.
-
VERIFIED (potwierdzony) - kroki potrzebne do odtworzenia błędu są poprawne.
-
CLOSED (zamknięty) - najczęściej oznacza to koniec życia raportu. Zostanie
on pogrzebany pod nigdy nie kończącą się listą nowych zgłoszeń.
Wkrótce po naszym zgłoszeniu, jeden z deweloperów znajduje problem w pliku
logowania strace, naprawia go i ustawia status raportu na RESOLVED FIXED,
wspominając, że zmieniło się położenie plików konfiguracyjnych, a opiekun
(czyli autor tekstu) uaktualni plik ebuild tak, aby ostrzegał o tym fakcie.
Problem jest rozwiązany, a nam wyświetla się poniższy ekran.
Ilustracja 7.8: Rozwiązany problem |
 |
Nieco niżej ujrzymy następujące opcje:
Ilustracja 7.9: Opcje raportu |
 |
Dają nam one możliwość ponownego otwarcia raportu (jeśli na przykład
deweloperowi wydaje się, że błąd został naprawiony, ale nam takie rozwiązanie
nie odpowiada). Nasz problem został naprawiony! Istnieć mogą jednak różne
możliwe rozwiązania. Oto krótka lista:
-
FIXED (naprawiony) - problem został rozwiązany. Aby naprawić nasz błąd,
powinniśmy zastosować się do instrukcji z raportu.
-
INVALID (nieprawidłowy) - błąd wystąpił z naszej winy, nie zrobiliśmy
czegoś zgodnie z dokumentacją.
-
DUPLICATE (duplikat) - nie skorzystaliśmy z niniejszego poradnika i
zgłosiliśmy już istniejący błąd.
-
WORKSFORME (u mnie działa) - deweloper lub osoba, której przydzielony
został raport nie jest w stanie odtworzyć błędu.
-
CANTFIX (nienaprawialne) - z jakiegoś powodu problem nie może zostać
rozwiązany. Powody zostaną podane przez osobę, do której został przypisany
raport.
-
WONTFIX (nie naprawimy) - najczęściej spotykane przy nowych plikach ebuild
lub prośbach o nową funkcjonalność. Zwykle oznacza to, że deweloper nie
chce dodać danej opcji, ponieważ nie jest ona potrzebna, istnieje lepsza
alternatywa albo po prostu nie będzie ona działać. Czasem otrzymamy
rozwiązanie naszego problemu.
-
UPSTREAM (prześlij do autora) - błąd nie może zostać poprawiony przez
deweloperów Gentoo i poprosili oni, aby został zgłoszony autorom danego
programu. Mogą oni stosować różne sposoby zgłaszania błędów, jak na
przykład listy mailingowe, kanały IRC, a nawet własne systemy takie jak
Bugzilla. Jeśli nie jesteśmy pewni jak się z nimi skontaktować, wystarczy
spytać w komentarzach do raportu.
Czasem zdarza się, że zanim problem będzie mógł zostać rozwiązany, deweloper
poprosi nas, byśmy przetestowali uaktualniony plik ebuild. W następnym
rozdziale przyjrzymy się testowaniu ebuildów.
8.
Testowanie plików ebuild
Pobieranie plików
Załóżmy, że zgłosiliśmy wcześniej błąd kompilacji programu foobar2.
Deweloperzy zorientowali się, w czym tkwi problem i chcą, abyśmy przetestowali
plik ebuild aby sprawdzić czy prawidłowo rozwiązuje nasz problem:
Ilustracja 8.1: Prośba o przetestowanie pliku ebuild |
 |
Użyto tu słownictwa, które może sprawiać nieco problemów. Po pierwsze
sprawdźmy, co to jest overlay (nakładka). Jest specjalny katalog podobny do
/usr/portage, z tą różnicą, że gdy wykonamy polecenie emerge
sync, pliki z niego nie zostaną skasowane. Specjalnie w tego celu stworzono
katalog /usr/local/portage. Ustawmy naszą nakładkę na portage w
pliku /etc/make.conf, dopisując w nim następującą linijkę.
Listing 8.1: Ustawianie zmiennej PORTDIR_OVERLAY |
PORTDIR_OVERLAY="/usr/local/portage"
|
Musimy teraz stworzyć odpowiednie katalogi, w których umieścimy nasz testowy
plik ebuild. W tym przypadku powinniśmy umieścić go w sys-apps/foobar2. Należy
zwrócić uwagę, że w drugim komentarzu mowa jest o katalogu files,
w którym umieścić należy łatkę. Ten katalog zawiera inne wymagane pliki, które
nie są dołączone do archiwum ze źródłami programu (m.in. poprawki, skrypty
init.d). Podkatalog files znajduje się w katalogu z pakietem.
Utwórzmy teraz wszystkie wymagane katalogi:
Listing 8.2: Tworzenie katalogów kategorii i pakietu |
# mkdir -p /usr/local/portage/sys-apps/foobar2/files
|
Uwaga:
Parametr -p polecenia mkdir spowoduje utworzenie nie tylko docelowego katalogu,
ale także wszystkich brakujących katalogów macierzystych po drodze (w tym
przypadku sys-apps i foobar2).
|
Teraz możemy pobrać pliki. Po pierwsze, ściągnijmy plik ebuild do
/usr/local/portage/sys-apps/foobar2, a następnie patch do
/usr/local/portage/sys-apps/foobar2/files. Skoro mamy już pliki,
możemy zabrać się do testowania.
Testowanie pliku ebuild
Proces tworzenia pliku ebuild, który będzie mógł zostać użyty w drzewie Portage
jest dość prosty. Musimy utworzyć plik Manifest (spis plików) oraz pliki
Manifest dla ebuilda. Dokonamy tego poleceniem ebuild uruchomionym jak poniżej.
Listing 8.3: Tworzenie plików Manifest |
# ebuild foobar2-1.0.ebuild manifest
>>> Creating Manifest for /usr/local/portage/sys-apps/foobar2
|
Sprawdźmy teraz czy plik ebuild działa jak powinien.
Listing 8.4: Testowanie za pomocą polecenia 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
|
Wygląda na to, że działa! Zwróćmy uwagę na oznaczenie [1] w linii zawierającej
[ebuild]. Wskazuje ono ścieżkę /usr/local/portage, czyli nakładkę,
którą stworzyliśmy wcześniej. Teraz możemy śmiało zainstalować program.
Listing 8.5: Wynik instalacji |
# 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
|
Na początku widzimy, że emerge działa tak jak do tej pory. Następnie widać, że
łatka nałożyła się poprawnie, o czym informuje nas komunikat "[ ok ]" po prawej
stronie. W końcu widzimy, że program skompilował się poprawnie. Łatka działa!
Możemy teraz powiadomić dewelopera, że może zamieścić poprawkę błędu w drzewie
Portage.
Podsumowanie
W ten sposób doszliśmy do końca niniejszego dokumentu o pracy z Bugzillą. Mamy
nadzieję, że był on przydatny. W razie jakichkolwiek pytań, pomysłów lub
komentarzy do tego dokumentu, prosimy o przesłanie ich pod adres
Chris White. Specjalne podziękowania należą się
moreonowi za uwagi o flagach -g i błędach kompilacji, ludziom z kanału IRC
#gentoo-bugs za pomoc w pracy nad częścią o raportowaniu błędów, Griffon26 za
uwagi na temat maintainer-needed, robbat2 za ogólne sugestie oraz fix2mike'owi
za poprawienie niniejszego dokumentu i dodawanie do niego nowych treści w miarę
potrzeb.
Materiał udostępniany na podstawie licencji Creative Commons -
Attribution / Share Alike.
|