Gentoo Logo

Zgłaszanie błędów w Gentoo

Spis treści:

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

(symbole debugowania usunięte)
-rwxr-xr-x  1 chris users 3140  6/28 13:11 zepsuty_kod
(symbole debugowania pozostawione)
-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

(bez symboli debugowania)
-rwxr-xr-x  1 chris users 3140  6/28 13:11 zepsuty_kod
(z symbolami debugowania)
-rwxr-xr-x  1 chris users 6374  6/28 13:10 zepsuty_kod
(z włączoną flaga -ggdb)
-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)

(Komunikaty kompilatora)
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

(Błąd budowania)
foobar2.c:1:17: ogg.h: No such file or directory
make: *** [foobar2.o] Error 1

(Błąd emerge)
!!! 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

Fig. 1

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

Fig. 2

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

Fig. 3

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ść

Fig. 4

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'
(Pozbywamy się apostrofów ' ')
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

Fig. 5

Kliknijmy więc na przycisku Search (szukaj) aby otrzymać wyniki...


Ilustracja 5.6: Wyniki wyszukiwania

Fig. 6

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

Fig. 7

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

Fig. 8

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

Fig. 1

Kliknijmy na odnośniku "Report a Bug -- Using the guided format" (Zgłoś błąd -- krok po kroku)


Ilustracja 6.2: Wybór produktu

Fig. 2

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

Fig. 3

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

Fig. 4

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

Fig. 5

  • 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

Fig. 6

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

Fig. 7

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ść

Fig. 8

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

Fig. 9

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

Fig. 10

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

Fig. 11

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

Fig. 1

Dostępne są także szczegółowe informacje, które podaliśmy.


Ilustracja 7.2: Szczegółowe informacje z raportu o błędzie

Fig. 2

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

Fig. 3

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

Fig. 4

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

Fig. 5

Dołączyliśmy plik strace.log i teraz widać go w naszym raporcie.


Ilustracja 7.6: Dołączony plik logowania przez strace

Fig. 6

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

Fig. 7

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

Fig. 8

Nieco niżej ujrzymy następujące opcje:


Ilustracja 7.9: Opcje raportu

Fig. 9

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

Fig. 1

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!
(wycięte komunikaty kompilacji)
>>> Unpacking foobar2-1.0.tar.bz2 to /var/tmp/portage/foobar2-1.0/work
 * Applying foobar2-1.0-Makefile.patch ...                                    [ ok ]
(wycięte komunikaty kompilacji)
>>> 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.



Drukuj

Zaktualizowano 5 marca 2009

Podsumowanie: Niniejszy dokument przedstawia prawidłowy sposób zgłaszania błędów przy użyciu Bugzilli Gentoo.

Chris White
Autor

Shyam Mani
Redaktor

Kuba Bożanowski
Tłumacz

Radosław Szkodziński
Tłumacz

Donate to support our development efforts.

Support OSL
Gentoo Centric Hosting: vr.org
Tek Alchemy
SevenL.net
Global Netoptex Inc.
Bytemark
Online Kredit Index
Copyright 2001-2009 Gentoo Foundation, Inc. Questions, Comments? Contact us.