[ Pobierz całość w formacie PDF ]
Po wystosowaniu pięciu komunikatów warunek kontynuowania diagnostyki jest już
zawsze fałszywy.
W obu ostatnich przykładach zmienne powinny być statyczne i lokalne względem
funkcji gwarantuje to podtrzymanie wartości zmiennej i tym samym kontynuowanie
strategii ograniczania w kolejnych wywołaniach funkcji.
%7ładen z powyższych przykładów nie jest zbyt dobrze przystosowany do działania
w środowisku wieloprocesorowym niedomaganie to można jednak szybko
wyeliminować, wdrażając w nich operacje niepodzielne. Ale prawdę mówiąc, w kodzie
diagnostycznym nie warto chyba zawracać sobie tym głowy.
Szukanie winowajcy wyszukiwanie binarne
Niejednokrotnie znaczną pomocą w wytypowaniu błędu jest wiedza o momencie,
w którym błąd pojawił się w jądrze, w sensie znajomości numeru wersji jądra, od której
zaczęto obserwować objawy błędu. Jeżeli na przykład wiadomo, że błąd ujawnił się
w wersji 2.6.33, ale nie w wersji 2.6.28, to sprawa jest jasna wytypowanie błędu polega
zazwyczaj na przejrzeniu i przeanalizowaniu listy zmian pomiędzy tymi wersjami
(niekiedy wystarczy wycofać feralną zmianę).
Wielokrotnie jednak nie wiadomo na pewno, w której wersji pojawił się dany błąd.
Wiadomo jedynie, że obecny jest w wersji bieżącej, i wydaje się, że był w tej wersji
od zawsze. Wtedy określenie momentu wprowadzenia błędu do kodu jądra wymaga
przeprowadzenia śledztwa, które przy odrobinie wysiłku zaowocuje jednak wytypowaniem
winowajcy. Po określeniu zmiany wprowadzającej błąd jego usunięcie jest zwykle kwestią
czasu, i to niezbyt długiego.
W takich poszukiwaniach potrzebny jest błąd, którego wystąpienie można w sposób
pewny sprowokować. Najlepiej, jeśli błąd daje się wywołać zaraz po zakończeniu rozruchu
systemu. Następnie należy zaopatrzyć się w jądro, co do którego wiadomo na pewno,
że jest wolne od rzeczonego błędu. Może to być na przykład jądro wykorzystywane kilka
miesięcy temu, na którym nigdy nie udało się sprowokować błędu. Równie dobrze może
to być jednak wersja znacznie wcześniejsza. O ile błąd nie czaił się w jądrze od zawsze,
poszukiwania takie dają zwykle wyniki stosunkowo szybko.
Kup książkę Poleć książkę
450 Rozdzia 18. Diagnostyka b dów j dra
Potrzebne jest też jądro, o którym wiadomo na pewno, że jest obarczone błędem.
Najlepiej, jeżeli będzie to jak najwcześniejsza wersja jądra na pewno zawierająca błąd.
Po uzyskaniu jądra poprawnego należy rozpocząć wyszukiwanie binarne od wersji
skażonej do wersji dobrej. Załóżmy, że najnowsze jądro, o którym wiadomo, że jest
wolne od błędu, to jądro 2.6.11, a najwcześniejsze jądro z błędem to jądro 2.6.20.
Poszukiwania należy rozpocząć od wersji w miarę równo odległej od obu wersji
skrajnych, na przykład 2.6.15. Jeżeli w wyniku testów okaże się, że wersja ta jest wolna
od błędu, to wiadomo, że błąd pojawił się w kodzie następnych wersji. Należy więc
zbadać wersję środkową pomiędzy wersjami 2.6.15 i 2.6.20 na przykład 2.6.17.
Jeżeli zaś test wykaże obecność błędu już w wersji 2.6.15, należy zawęzić poszukiwania
do wersji 2.6.11 2.6.15 i rozpocząć je od na przykład wersji 2.6.13. Poszukiwania trzeba
następnie kontynuować w odpowiednich połówkach tak ograniczonego zakresu wersji.
W końcu kolejne testy doprowadzą do zawężenia zakresu poszukiwań do dwóch
kolejnych wersji jądra, w których jedna będzie obarczona błędem, a druga będzie od
niego wolna. W tym momencie można już w prosty sposób określić pechową zmianę
pomiędzy wersjami. Warto zauważyć, że taki sposób przeszukiwania jest znacznie
efektywniejszy niż przeszukiwanie wszystkich kolejnych wersji jądra!
Binarne wyszukiwanie wersji za pomoc Gita
System zarządzania zmianami w kodzie zródłowym Git udostępnia użytkownikom
bardzo przydatny i wygodny mechanizm przeprowadzania binarnego wyszukiwania
wersji. Każdy, kto kontroluje kopię drzewa kodu zródłowego jądra systemu Linux za
pośrednictwem Gita (a jest to metoda preferowana i powszechnie stosowana), może
zautomatyzować wyszukiwanie feralnej wersji, składając go na samo repozytorium.
Co więcej, Git pozwala na przeprowadzenie wyszukiwania binarnego nie według wersji
wydawniczych jądra, ale według zmian zatwierdzanych do repozytorium, a więc
z dokładnością do jednej rewizji (wersje wydawnicze to agregaty nawet setek rewizji kodu
jądra). Dodatkowo sama operacja jest naprawdę prosta (co w przypadku Gita nie zawsze
jest oczywiste). Na początek wystarczy zażądać rozpoczęcia wyszukiwania binarnego:
$ git bisect start
Następnie podaje się najwcześniejszą znaną rewizję, w której błąd występował:
$ git bisect bad rewizja
Jeśli nie wiadomo, w której wersji błąd się ujawnił, nie trzeba w ogóle podawać rewizji
Git domyślnie uzna, że chodzi o rewizję najnowszą:
$ git bisect bad
Potem podaje się najpózniejszą rewizję, o której wiadomo, że nie zawierała błędu:
$ git bisect good v2.6.28
Kup książkę Poleć książkę
Koledzy kiedy wszystko inne zawiedzie 451
[ Pobierz całość w formacie PDF ]