Idź do
• Spis treści
• Przykładowy rozdział
Helion SA
ul. Kościuszki 1c
44-100 Gliwice
tel. 32 230 98 63
© Helion 1991–2010
Katalog książek
Twój koszyk
Cennik i informacje
Czytelnia
Kontakt
Debugowanie. Jak wyszukiwaæ
i naprawiaæ b³êdy w kodzie
oraz im zapobiegaæ
Autor:
T³umaczenie: Andrzej Gra¿yñski
ISBN: 978-83-246-2760-8
Tytu³ orygina³u:
Format: 158235, stron: 240
Mistrz debugowania w akcji!
• Jak tworzyæ oprogramowanie, które ³atwo siê debuguje?
• Jak wykrywaæ potencjalne przyczyny problemów?
• Jak omin¹æ pu³apki czyhaj¹ce na programistów?
Zapewne niejednokrotnie podczas pracy przy komputerze musia³eœ u¿eraæ siê z wadliwymi
aplikacjami. Doskonale wiesz, jak to jest, kiedy kolejne ³atki usuwaj¹ stare b³êdy,
równoczeœnie generuj¹c nowe, programiœci zaœ nie kwapi¹ siê do zmiany niew³aœciwych
za³o¿eñ. A przecie¿ jednym z najbardziej niedocenianych aspektów profesjonalnego
programowania jest zdolnoœæ do rozpoznawania i usuwania b³êdów kryj¹cych siê
w ka¿dej wiêkszej partii stworzonego kodu. Jeœli tworzysz niebanalne aplikacje,
najprawdopodobniej zajmiesz siê ich debugowaniem chwilê po zakoñczeniu ich pisania.
To zajêcie w zdecydowanie wiêkszym stopniu ni¿ inne aspekty tworzenia oprogramowania
jest dzia³alnoœci¹ intelektualn¹ – poniewa¿ jego aren¹ jest umys³ programisty.
Znajdowanie i wyjaœnianie przyczyn problemów powinno byæ pierwsz¹ czynnoœci¹ na
drodze do ich zwalczania.
Ta ksi¹¿ka poœwiêcona jest w³aœnie arkanom sztuki debugowania. Jej lektura pozwoli
Ci znacznie ograniczyæ liczbê pope³nianych b³êdów, a te, które siê pojawi¹, bêd¹
³atwiejsze do wykrycia i usuniêcia. Podrêcznik wyjaœni Ci, jak pisaæ kod, który ³atwo
debugowaæ, przeprowadzi Ciê przez proces wykrywania b³êdów, ich reprodukcji,
diagnozowania, a¿ do wprowadzania i wycofywania poprawek w oprogramowaniu.
Poznaj empiryczn¹ metodê wykrywania b³êdów. Dowiedz siê, jak wa¿ne jest zapewnienie
sobie pewnych sposobów reprodukowania b³êdnych zachowañ. Naucz siê unikaæ
pu³apek czyhaj¹cych zarówno na programistów, jak i testerów. Stosuj powszechnie
u¿ywane narzêdzia i metody zapewniaj¹ce automatyczne wykrywanie potencjalnych
przyczyn problemów, zanim jeszcze siê one pojawi¹! Naucz siê tworzyæ samodebuguj¹ce
oprogramowanie, które automatycznie informuje o swoim stanie, a tak¿e sprawdŸ, co
mo¿esz zrobiæ, aby szybko wykrywaæ sytuacje bêd¹ce potencjaln¹ przyczyn¹ problemów.
• Metoda empiryczna
• Reprodukcja b³êdów
• Diagnozowanie
• Wyszukiwanie b³êdów
• Wprowadzanie i wycofywanie poprawek
• Testowanie
• Przyczyny b³êdów
• Oprogramowanie samodebuguj¹ce
• Narzêdzia wspomagaj¹ce
Spis treci
Od tumacza sów kilka .................................................................................... 9
Przedmowa ...................................................................................................... 13
Cz I. Istota problemu
Rozdzia 1. W tym szalestwie jest metoda ................................................ 19
1.1. Debugowanie to co wicej ni eksterminacja bdów ................................................ 20
1.2. Metoda empiryczna ................................................................................................ 22
1.3. Struktura procesu debugowania .............................................................................. 23
1.4. Przede wszystkim rzeczy najwaniejsze .................................................................... 24
1.5. Do dziea! ............................................................................................................. 28
Rozdzia 2. Reprodukcja ................................................................................. 29
2.1. Najpierw reprodukcja, potem pytania ...................................................................... 29
2.2. Kontrolowane zachowanie aplikacji ......................................................................... 32
2.3. Kontrolowane rodowisko ....................................................................................... 32
2.4. Kontrolowane dane wejciowe ................................................................................. 34
2.5. Ulepszanie reprodukcji ........................................................................................... 43
2.6. Gdy bd nie chce si ujawni ................................................................................. 52
2.7. Podsumowanie ...................................................................................................... 55
Rozdzia 3. Diagnoza ....................................................................................... 57
3.1. Gdy debugowanie staje si nauk ............................................................................ 57
3.2. Sztuczki i chwyty .................................................................................................... 63
3.3. Debuggery ............................................................................................................. 70
6
Debugowanie
3.4. Puapki ................................................................................................................. 71
3.5. Gry umysowe ........................................................................................................ 76
3.6. Zweryfikuj swoj diagnoz ...................................................................................... 80
3.7. Podsumowanie ...................................................................................................... 81
Rozdzia 4. Poprawki ...................................................................................... 83
4.1. Czysta tablica ........................................................................................................ 84
4.2. Testowanie ............................................................................................................ 85
4.3. Eliminowanie przyczyn, nie objawów ....................................................................... 87
4.4. Refaktoryzacja ....................................................................................................... 89
4.5. Kontrola wersji ...................................................................................................... 91
4.6. Inspekcja kodu ....................................................................................................... 92
4.7. Podsumowanie ...................................................................................................... 93
Rozdzia 5. Refleksja ....................................................................................... 95
5.1. Jak to w ogóle mogo dziaa? ................................................................................. 95
5.2. Co poszo nie tak? .................................................................................................. 97
5.3. Nigdy wicej tego samego bdu .............................................................................. 99
5.4. Zamykanie ptli ................................................................................................... 102
5.5. Podsumowanie .................................................................................................... 102
Cz II. Szersza perspektywa
Rozdzia 6. Chyba mamy problem… ........................................................... 105
6.1. Tropienie bdów ................................................................................................. 106
6.2. Wspópraca z uytkownikami ................................................................................ 109
6.3. Wspódziaanie z innymi zespoami ....................................................................... 116
6.4. Podsumowanie .................................................................................................... 117
Rozdzia 7. Pragmatyczna nietolerancja .................................................... 119
7.1. Bdy maj pierwszestwo .................................................................................... 119
7.2. Debugowanie a psychologia .................................................................................. 122
7.3. Zasypywanie przepaci jakociowej ....................................................................... 125
7.4. Podsumowanie .................................................................................................... 129
Cz III. Debug-Fu
Rozdzia 8. Przypadki szczególne ................................................................ 133
8.1. atanie istniejcego oprogramowania .................................................................... 133
8.2. Kompatybilno wersji .......................................................................................... 134
8.3. Wspóbieno ..................................................................................................... 139
Spis treci
7
8.4. Bdy heisenbergowskie ........................................................................................ 142
8.5. Problemy z wydajnoci ....................................................................................... 144
8.6. Systemy osadzone ................................................................................................ 147
8.7. Bdy w obcym oprogramowaniu ........................................................................... 150
8.8. Podsumowanie .................................................................................................... 154
Rozdzia 9. Idealne rodowisko debugowania .......................................... 155
9.1. Automatyczne testowanie ..................................................................................... 155
9.2. Kontrola wersji .................................................................................................... 158
9.3. Automatyczne budowanie binariów ....................................................................... 163
9.4. Podsumowanie .................................................................................................... 171
Rozdzia 10. Naucz swe oprogramowanie samodebugowania ................ 173
10.1. Zaoenia i asercje ............................................................................................. 174
10.2. Binaria debugowalne .......................................................................................... 184
10.3. Wycieki zasobów i bdna obsuga wyjtków ........................................................ 189
10.4. Podsumowanie .................................................................................................. 195
Rozdzia 11. Antywzorce .............................................................................. 197
11.1. Inflacja priorytetów ............................................................................................. 197
11.2. Primadonna ....................................................................................................... 198
11.3. Zespó serwisowy ............................................................................................... 200
11.4. Gaszenie poaru ................................................................................................ 202
11.5. Pisanie od nowa ................................................................................................. 203
11.6. Bezpaski kod ................................................................................................... 205
11.7. Czarna magia .................................................................................................... 206
11.8. Podsumowanie .................................................................................................. 207
Dodatki
Dodatek A Materiay .................................................................................... 211
A.1. Systemy kontroli wersji i ledzenia problemów ....................................................... 211
A.2. Narzdzia zarzdzania generowaniem binariów i integracj cig .......................... 215
A.3. Przydatne biblioteki ............................................................................................ 216
A.4. Inne narzdzia .................................................................................................... 218
Skorowidz ...................................................................................................... 223
Rozdzia 1. • W tym szalestwie jest metoda
19
Rozdzia 1.
W tym szalestwie
jest metoda
ego mona si byo spodziewa: stworzony program nie chce dziaa, a jeeli
ju dziaa, to w sposób dziwaczny. I co teraz?!
Niewtpliwie poyteczny okazuje si wówczas nawyk systematycznoci, czyli
denie do znalezienia prawdziwej przyczyny (przyczyn) tak dziwacznego zachowania
(starannie przecie napisanego) programu, wielu programistów jednak zdaje si
wykazywa objawy chaotycznego — by nie rzec rozpaczliwego — miotania si po
kodzie programu, bez wyranego celu i (co zrozumiae) bez widocznych rezultatów.
Có jednak odrónia obie te grupy od siebie?
W tym rozdziale przyjrzymy si dokadnie metodom debugowania kodu, sprawdzo-
nym w warunkach profesjonalnego wytwarzania oprogramowania. Nie da si ich, co
prawda, porówna do kamienia filozoficznego, zamieniajcego powszedni materi
— czyli owoc niedoskonaych dziaa omylnych programistów — w zoto, czyli kod
dziaajcy niezawodnie i bezbdnie; w dalszym cigu nieocenione okazuj si okre-
lone kwalifikacje programisty czy testera — wiedza, dowiadczenie, intuicja, zdolno-
ci detektywistyczne, no i — oczywicie — odrobina szczcia. Metody te umoliwiaj
odpowiednie ukierunkowanie zainwestowanego wysiku, pozwalaj unikn bezsen-
sownego drenia rozmaitych hipotez, a w konsekwencji otwieraj drog — moliwie
krótk — dotarcia do prawdziwej przyczyny problemu. Poznamy kilka konkretnych
koncepcji, skadajcych si na wspomnian metodologi, m.in.:
rónic midzy „debugowaniem” a „usuwaniem bdów”,
podejcie empiryczne, czyli niech oprogramowanie samo zademonstruje,
co si z nim dzieje,
T
20
Cz I • Istota problemu
podstawowe elementy procesu debugowania — reprodukowanie bdów,
diagnozowanie ich przyczyny, poprawianie kodu i wyciganie wniosków
na przyszo,
konieczno dokadnego rozumienia sensu podejmowanych dziaa.
1.1. Debugowanie to co wicej
ni eksterminacja bdów
Spytajcie niedowiadczonego programist, co oznacza termin „debugowanie”, a usy-
szycie, e jest to „znajdowanie bdów” czy inn podobn odpowied. Oczywicie,
eliminowanie bdów jest jednym z elementów debugowania, nie jest to jednak
element jedyny ani nawet najwaniejszy. Efektywne debugowanie ukierunkowane
jest pod ktem istotnych celów. Oto one.
1.
Znalezienie przyczyny nieoczekiwanego zachowania programu.
2.
Wyeliminowanie tej przyczyny.
3.
Zapobieganie sytuacjom, w których wyeliminowanie jednej przyczyny
jednej grupy bdów staje si kolejn przyczyn innych bdów.
4.
Utrzymanie (a nawet ulepszenie) ogólnej jakoci kodu — jego czytelnoci,
przejrzystoci, stopnia pokrycia przypadkami testowymi, wydajnoci, atwoci
konserwacji i rozbudowy itp.
5.
Upewnienie si, e okrelony problem zosta cakowicie wyeliminowany
z kodu programu i nie da zna o sobie nigdy wicej.
Nieprzypadkowo najwaniejszy okazuje si pierwszy z wymienionych celów — od
prawidowego rozpoznania rzeczywistej przyczyny problemu uzalenione jest po-
wodzenie pozostaych dziaa.
Przede wszystkim — zrozumie
Pocztkujcy, niedowiadczeni programici (i, niestety, wielu uwaajcych si za
dowiadczonych) czsto zaniedbuj rozpoznanie problemu „u róda”, ograniczajc
si do dokonywania doranych poprawek, które powinny przywróci
1
poprawne
1
Nie mona, oczywicie, przywróci czego, czego nigdy nie byo, szczególnie nie mona przywróci
poprawnego dziaania programu, który nigdy poprawnie nie dziaa. To prawda, nie zapominajmy
jednak, e kady tworzony przez nas program funkcjonuje poprawnie w naszych oczekiwaniach,
w naszej wyobrani (a bywa i tak, e faktycznie okazuje si od razu bezbdny — najbardziej
odpowiednim pytaniem pod adresem programisty moe by wówczas: „Co zamierzasz zrobi na bis?”).
Umówmy si wic, i owo „przywrócenie” oznacza przywrócenie adekwatnoci naszych oczekiwa
po pocztkowo frustrujcej konfrontacji z rzeczywistoci — przyp. tum.
Rozdzia 1. • W tym szalestwie jest metoda
21
funkcjonowanie programu. Gdy programista ma troch szczcia, owe dorane zabiegi
okazuj si od razu chybione, co umoliwia uniknicie marnotrawstwa czasu i wysiku,
niekiedy jednak, niestety, faktycznie eliminuj konkretny bd lub stwarzaj pozory
jego wyeliminowania. „Niestety”, poniewa w ostatecznym rozrachunku okazuje si,
e owe nieprzemylane i nie do koca zrozumiane zabiegi jedynie maskuj prawdziwe
przyczyny bdów, które niespodziewanie mog si ujawni, gdy bdziemy tego naj-
mniej oczekiwa. Co gorsza, nieprzemylane atanie kodu moe mie zgubne konse-
kwencje w postaci destrukcji regresywnej, czyli ponownego wprowadzenia do kodu
bdów, których przyczyny zostay wczeniej wyeliminowane.
Zmarnowany czas i wysiek
Kilka lat temu przyszo mi wspópracowa z zespoem bardzo dowiadczonych
i utalentowanych programistów. Swe zawodowe umiejtnoci zdobywali oni
na bazie systemów klasy UNIX, jednak gdy do nich doczyem, dokonywali
migracji uniksowego oprogramowania na platform Windows; migracja ta
znajdowaa si ju w do zaawansowanym stadium.
Jeden z „bdów” wynikajcych z migracji ujawnia si w warunkach rów-
nolegej pracy wielu wtków. Niektóre wtki funkcjonoway bez zarzutu,
inne jednak zdaway si pozostawa w stanie zagodzenia
2
. Poniewa
w rodowisku UNIX-a wszystko funkcjonowao bezbdnie, przyczyna
problemu zdawaa si ewidentnie tkwi w specyfice mechanizmu zarzdzania
wtkami przez Windows. Podjto wic decyzj o stworzeniu wasnego pod-
systemu zarzdzania wtkami, zastpujcego oferowany standardowo przez
Windows — przedsiwzicie, owszem, bardzo ambitne i pracochonne, nie-
mniej jednak mieszczce si w granicach moliwoci wspomnianego zespou.
I rzeczywicie, gdy doczyem do zespou, wydawao si, e wspomniany
podsystem spenia pokadane w nim nadzieje — nie zdarzay si ju
przypadki zagodzenia wtków. Jednak tak gboka ingerencja w system
operacyjny rzadko obywa si bez skutków ubocznych i nie inaczej byo tym
razem: cen zapacon za ulepszone zarzdzanie wtkami okazao si ogólne,
zauwaalne spowolnienie pracy caego systemu Windows.
Dla mnie caa ta sytuacja bya o tyle intrygujca, e sam w przeszoci
musiaem zmaga si z rozmaitymi problemami wynikajcymi z wielowtkowej
architektury tworzonych przeze mnie aplikacji dla Windows. Pobiena analiza
problemu, którego konsekwencj bya gboka ingerencja w system operacyjny,
wykazaa, e jego rzeczywist przyczyn jest dynamiczne zwikszanie priorytetu
wtków (dynamic thread priority boost), które wyczy mona w sposób
2
Zagodzeniem (starvation) wtku lub procesu nazywamy sytuacj, w której mechanizmy szere-
gowania systemu operacyjnego konsekwentnie ignoruj ów wtek lub proces w rywalizacji o dostp
do zasobów, w tym przypadku w rywalizacji o czas procesora — przyp. tum.
22
Cz I • Istota problemu
elementarny, wywoujc funkcj API
SetThreadPriorityBoost()
. Zamiast
pracochonnego — i podatnego na bdy — tworzenia wasnego systemu
szeregowania wtków, wystarczyoby dodanie jednego wiersza kodu.
Mora? Obserwujc niepodane zachowanie aplikacji, zespó programistów
dopatrzy si jego przyczyny w ogólnej architekturze Windows, bez gbszej
analizy uwikanego w to zachowanie podsystemu. Na pewno nie bez znaczenia
byy uwarunkowania kulturowe, czyli mówic po prostu, acz delikatnie, nie
najlepsza reputacja systemu Windows w rodowisku „hakerów uniksowych”.
Tak czy inaczej, gdyby programici z zespou powicili nieco czasu na
wnikliw analiz zjawiska i tkwicych u jego przyczyny mechanizmów oraz
dostpnych ustawie, zaoszczdziliby znacznie wicej czasu, jaki stracony
zosta na — niepotrzebn w gruncie rzeczy — konstrukcj wasnego
podsystemu. Uniknliby ponadto degradacji wydajnoci systemu Windows
i (bez wtpienia) wprowadzenia do nowych bdów.
Mówic dosadnie: gdy rezygnujemy z poszukiwa prawdziwych przyczyn ujawniaj-
cych si bdów, sami wystawiamy si poza nawias inynierii programowania, za-
puszczamy si w zdradliwy gszcz „programowania voodoo”
3
lub „lub programowania
przez przypadek”
4
.
1.2. Metoda empiryczna
Do zrozumienia przyczyny zaistniaych bdów, manifestujcych si niezgodnym
z oczekiwaniami dziaaniem aplikacji, mona dochodzi rónymi drogami. Generalnie
kada metoda, która przyblia do tego celu, moe by uznana za waciw.
A skoro tak, to w wikszoci przypadków debugowania najbardziej celowe — bo
wysoce produktywne —okazuje si podejcie empiryczne.
Podejcie to zasadza si na obserwacjach i dowiad-
czeniu, a nie na teorii czy te czysto logicznych spe-
kulacjach. Owszem, mona studiowa kod programu
i wyciga z niego wnioski na temat skutków wykonania
poszczególnych jego fragmentów (i czasem zdarza si, e nie ma innego wyboru),
3
argonowe okrelenie naladujce powiedzenie prezydenta George’a Busha seniora, który mia-
nem „voodoo economics” okrela niektóre gospodarcze posunicia Ronalda Reagana. Oznacza
uywanie w programowaniu funkcji lub algorytmów, których dziaania nie rozumie si w peni,
wskutek czego program nie dziaa albo jeli przypadkiem dziaa, programista i tak nie rozumie, dla-
czego tak si dzieje, cytat z
pl.wikipedia.org
—
przyp. tum.
4
Andrew Hunt, David Thomas, The Pragmatic Programmer: From Journeyman to Master, Addi-
son-Wesley, Reading, MA, 2000.
Eksperymentuj
i obserwuj wyniki.
Rozdzia 1. • W tym szalestwie jest metoda
23
A propos natury oprogramowania…
„Oprogramowanie” to kategoria zasugujca na szczególn uwag — co dla
nas, majcych z ni do czynienia na bieco, nie zawsze jest oczywiste.
Niewiele jest w ludzkiej dziaalnoci innych obszarów dajcych tak wielk oka-
zj do nieograniczonej niemal realizacji wasnej pomysowoci, wynalazczoci;
niewiele jest przykadów tworzywa intelektualnego dajcego si ksztatowa
w tak plastyczny sposób. Oprogramowanie ma t cenn zalet, e jest noni-
kiem determinizmu — poza nielicznymi wyjtkami, które opiszemy w dalszej
czci ksiki, kolejny stan jego realizacji wyznaczony jest jednoznacznie przez
stany poprzednie, a my uzyskujemy powtarzalny dostp do kadego ze stanów
na kade danie.
Nie maj tego szczcia przedstawiciele wikszoci dziedzin tradycyjnej inynierii.
Bo czy mona wyobrazi sobie mechanika Formuy 1, przygldajcego si sil-
nikowi obracajcemu si z prdkoci 19000 obrotów na minut i momentalnie
— jakby w rezultacie mentalnego zatrzymania tych obrotów — zgbiajcego
wszelkie detale rozmaitych konsekwencji tej dynamiki? Albo szczegóowo ana-
lizujcego przebieg zaponu w komorze spalania? W konfrontacji z szybkoci
dziaania ludzkich zmysów wydaje si to absolutnie niewykonalne i faktycznie
takie jest.
W naszym oprogramowaniu krcca si z szybkoci milionów (czy nawet mi-
liardów) na sekund ptla wolna jest od owego pitna ulotnoci. Gdy na danie
zostaje zatrzymana — w precyzyjnie okrelonym miejscu — moemy drobiazgo-
wo, bez presji wynikajcej z szalonego tempa, analizowa wszelkie (dostpne)
aspekty jej realizacji — przypomnijmy: aspekty deterministyczne, a wic powta-
rzalne. I ten wanie istotny fakt predestynuje metod empiryczn jako szczególnie
cenn i produktywn w procesie debugowania.
lecz jest to metoda po pierwsze, mao efektywna, po drugie, zawodna. Znacznie
efektywniej mona doj sedna problemu, konstruujc odpowiedni eksperyment i ob-
serwujc faktyczne zachowanie si aplikacji. Jest to nie tylko efektywne, lecz daje
take okazj do zweryfikowania przyjtych zaoe dotyczcych oczekiwanego jej
zachowania. Tak oto skutecznym narzdziem w walce z tkwicymi w oprogramo-
waniu bdami okazuje si… samo oprogramowanie.
W kolejnym punkcie zobaczymy, jak wykorzysta t empiryczn filozofi do utwo-
rzenia strukturalnego modelu walki z bdami w oprogramowaniu.
1.3. Struktura procesu debugowania
Pod wzgldem strukturalnym w procesie debugowania wyróni mona nastpu-
jce kluczowe elementy:
24
Cz I • Istota problemu
reprodukcj — czyli wypracowanie sposobów na niezawodn i wygodn
powtarzalno poszczególnych aspektów bdnego zachowania aplikacji;
diagnoz — formuowanie i eksperymentalne weryfikowanie hipotez,
zmierzajce do ostatecznego ustalenia rzeczywistej przyczyny zaistniaych
bdów;
napraw — projektujc i urzeczywistniajc zmiany w kodzie ródowym
w celu wyeliminowania konkretnego bdu, naley upewni si, e nie
spowoduj one zniwelowania poprawek wprowadzonych wczeniej (a w kon-
sekwencji ponownego zaistnienia bdów ju wyeliminowanych — powszech-
nie okrela si to zjawisko mianem destrukcji regresywnej); wprowadzane
poprawki nie powinny te pogarsza wydajnoci kodu, jego czytelnoci
i atwoci konserwacji;
refleksj — skuteczne poprawienie bdu staje si swoist lekcj, z której
warto zawsze wycign stosowne wnioski. Co zrobilimy nie tak w tym
fragmencie programu? Czy istniej inne jeszcze fragmenty noszce zna-
mi analogicznej pomyki? Co moemy zrobi w celu upewnienia si, e
tego bdu ju nie powtórzymy?
Jak pokazano na rysunku 1.1, etapy te zasadniczo
ukadaj si w prost sekwencj; nie powinno to jednak
sugerowa, i powizane s ze sob na zasadzie wo-
dospadu. Co prawda, trudno przystpowa do formu-
owania hipotez bez uprzedniego zapewnienia rodków do reprodukowania bdu na
danie, nie ma te wikszego sensu poprawianie kodu bez uprzedniego dogbnego
zrozumienia przyczyny wykrytego bdu, niemniej jednak midzy wymienionymi
czterema etapami istniej silne sprzenia zwrotne powodujce, e debugowanie,
zamiast sekwencj etapów, staje si procesem iteracyjnym. I tak np. na etapie formu-
owania hipotez moemy krytycznie oceni skuteczno metod reprodukowania b-
dów (i skuteczno t poprawi), za nanoszenie poprawek w kodzie moe sta si
okazj do zrewidowania przyjtych hipotez.
W nastpnych rozdziaach zatrzymamy si szczegóowo na kadym z wymienio-
nych etapów; dalsza cz tego rozdziau niech natomiast posuy jako niezbdne
do tego przygotowanie.
1.4. Przede wszystkim rzeczy najwaniejsze
Mimo silnej pokusy, by jak najszybciej „zacz debugowanie”, warto jednak za-
stanowi si, czy jestemy do tego naleycie przygotowani.
Debugowanie jest
procesem iteracyjnym.
Rozdzia 1. • W tym szalestwie jest metoda
25
Rysunek 1.1.
Struktura procesu debugowania
Czy naprawd wiesz, czego szukasz?
Zanim przystpimy do reprodukowania problemu i sta-
wiania hipotez na temat jego przyczyny, powinnimy
dokadnie zdawa sobie spraw z tego, có w zacho-
waniu aplikacji wydarzyo si takiego, co skonni jeste-
my uwaa za ów „problem”, oraz — co niemniej
wane — co powinno si wydarzy, zgodnie z naszymi oczekiwaniami. Jeli dys-
ponujemy formalnym raportem na temat bdów, raport ten powinien zawiera
niezbdne informacje w tym zakresie (raportami takimi zajmiemy si dokadniej w roz-
dziale 6.), na przeanalizowanie i zrozumienie których warto powici troch czasu.
Jeli nie ma raportu, bo bd sami wykrylimy lub dowiedzielimy si o nim z niefor-
malnej rozmowy, tym waniejsze jest stworzenie adekwatnego obrazu caej sytuacji.
Nie zapominajmy jednak, e formalne raporty o bdach bywaj nie mniej mylce ni
wszelkie inne dokumenty. Jeeli mianowicie stwierdzono w raporcie, e „wydarzyo
si to, a powinno si wydarzy tamto”, czy zawsze stwierdzenie takie zgodne jest ze
specyfikacj aplikacji? Jeeli mamy w tym wzgldzie wtpliwoci, nie rozpoczynajmy
konkretnych dziaa przed ich wyjanieniem, przed upewnieniem si, e wszystko
naleycie zrozumielimy. Nie warto ryzykowa „psucia” aplikacji, czyli zmiany
podanego jej zachowania na bdn, tylko dlatego, e tak sugerowa moe tre
wspomnianego raportu.
Co powinno si wydarzy,
a co wydarzyo si
naprawd?
26
Cz I • Istota problemu
Walka z niespójnymi danymi
Przyszo mi kiedy zmaga si z do prostym (wydawaoby si) bdem:
raport transakcji, generowany przez system ewidencji sprzeday, nie uwzgld-
nia czasu letniego i okazywa si nieadekwatny do rzeczywistoci w dniach,
na przeomie których nastpowaa zmiana czasu. Szybko wprowadziem
niezbdn poprawk i zajem si nastpnym problemem.
Niedugo potem poinformowano mnie o kolejnym bdzie: wykazana w rapor-
cie liczba transakcji nie zgadzaa si z liczb transakcji faktycznie zreali-
zowanych, wskutek czego dzia ksigowoci nie móg sporzdzi bilansu.
ródo owej rozbienoci od razu stao si dla mnie oczywiste: proces reje-
strowania transakcji nie uwzgldnia zmiany czasu, w przeciwiestwie do ge-
nerowanego raportu. Po krótkich konsultacjach dowiedziaem si, e opisany
problem da o sobie zna ju rok temu i wanie dla uniknicia opisanej
rozbienoci postanowiono istnienie czasu letniego po prostu ignorowa
5
.
Tak oto „bdne” dziaanie aplikacji, czyli rozbieno jej zachowania z ocze-
kiwaniami, nie byo wcale win aplikacji, a wynikao po prostu z nieadekwat-
noci wspomnianych oczekiwa. Poniewa raporty sprzeday generowane
byy w rónych kontekstach, niektóre powinny uwzgldnia zmian czasu,
inne raczej celowo j ignorowa. Rzetelnym rozwizaniem problemu mogoby
by wprowadzenie do programu stosownej opcji rozróniajcej te dwa
przypadki.
Jeden problem na raz
Poniewa problemy czsto pojawiaj si w grupach, istnienie pokusa zajmowania si
równolegle wieloma z nich. Pokusa taka okazuje si jeszcze silniejsza, gdy wiele
bdów wydaje si by zwizanych z tym samym obszarem kodu.
Takim pokusom naley si zdecydowanie opiera. Debugowanie jest procesem wy-
starczajco zoonym, by powstrzyma si od dalszej jego komplikacji. Jakkolwiek
nie bylibymy ostroni, zawsze istnieje moliwo, i eksperyment zmierzajcy do
wykrycia przyczyny jednego bdu interferowa moe z eksperymentami zaprojekto-
wanymi w celu wykrycia innych. To w duym stopniu utrudnia moe rozumienie,
co naprawd dzieje si z aplikacj. Ponadto wprowadzanie do kodu kadej poprawki
powinno by logicznie uzasadnione, a to staje si znacznie utrudnione, gdy próbujemy
poprawia kilka bdów na raz (wrócimy do tej kwestii w punkcie 4.5).
5
Prawd mówic, programista dokonujcy poprawek móg zaoszczdzi nam fatygi i umieci w kodzie
komentarz wyjaniajcy przyczyn ignorowania czasu letniego i tym samym upewniajcy czytelnika
kodu, e jest to dziaanie zamierzone.
Rozdzia 1. • W tym szalestwie jest metoda
27
Czasami moe si okaza, e to, co skonni bylimy uwaa za pojedynczy bd,
spowodowane jest wieloma przyczynami. Uwiadamiamy sobie wówczas, e znaleli-
my si w przysowiowej „strefie mroku” — z aplikacj dziej si róne kuriozalne
rzeczy, niedajce si wyjani w wiarygodny sposób. Obszernie problem ten omówiono
w punkcie 3.4.
Zaczynaj od rzeczy prostych
Wiele bdów programistycznych ma swe ródo w zwykym przeoczeniu tych czy
innych rzeczy. Mimo i czsto przychodzi nam zmaga si z bdami bardziej subtelnej
natury, nie mona o takich prozaicznych przyczynach zapomina.
Tak si ju stao, e my, programici, przekonani jestemy co do tego, e wszystko
powinnimy robi we wasnym zakresie. Przekonanie to czsto ujawnia si w postaci
syndromu „co nie moje, to niedobre” (Not Invented Here), polegajcego na ponow-
nym wynajdywaniu koa, czyli (uomnego nieraz) implementowania rzeczy, dla których
gotowe, czsto perfekcyjne implementacje, dostpne s na wycignicie rki. W odnie-
sieniu do debugowania syndrom ten przyjmuje posta denia do osobistego wyja-
nienia kadego aspektu nieoczekiwanego zachowania aplikacji.
A wystarczy po prostu spyta kolegów, czy w przeszoci zetknli si z takim, czy
innym problemem. To niewiele kosztuje, a moe przyczyni si do uniknicia znacz-
nego marnotrawstwa czasu i wysiku. Szczególnie w sytuacji, gdy nie jestemy eks-
pertami w dziedzinie, któr przyszo si nam zajmowa.
Niespójno treci Subversion
(Sean Ellis)
Nie dalej jak kilka dni temu nasz nowy kolega zetkn si z problemem dziw-
nego dziaania polecenia
svn export
. Dziwnego, bo mimo identycznych
numerów wersji, posta kodu aplikacji na serwerze Subversion rónia si od
kopii roboczej w jego komputerze. Nic, tylko rwa wosy z gowy.
Po bezskutecznych próbach samodzielnego uporania si z problemem kolega
podda si i zapyta mnie, czy widz jakie wyjanienie rozbienoci, któr on
jest mi w stanie natychmiast zaprezentowa.
Odpowiedziaem twierdzco, wyjaniajc, i przyczyn problemu jest bd
w jednej z bibliotek runtime serwera Apache, manifestujcy si pod posta-
ci nieprawidowej interpretacji cieek zawierajcych sekwencje
../../..
.
Po ostatecznym upewnieniu si, i to wanie jest istot problemu, wystar-
czyo nam kilka minut, by zainstalowa nowsz, poprawn wersj biblioteki.
Ostatecznie okazao si, i bd ten odkryty zosta ju wiele miesicy
wczeniej, jednak odkrywca widocznie zapomnia podzieli si sw wiedz
z kolegami.
28
Cz I • Istota problemu
Jak wida, komunikacja jest zawsze istotna — nie tylko w kwestiach subtel-
nych, trudnych do pisania zwykymi sowami, lecz take wówczas, gdy wystar-
czy po prostu zapyta: „Czy widzielicie ju wczeniej co podobnego?”.
W nastpnych rozdziale zajmiemy si pierwszym z etapów iteracyjnego debugowania
— reprodukowaniem bdnego zachowania aplikacji.
1.5. Do dziea!
Dla przypomnienia...
Upewnij si, e:
dysz do poznania prawdziwej przyczyny, powodujcej nieoczekiwane
zachowanie aplikacji,
rzeczywicie eliminujesz okrelony bd,
nie stwarzasz zagroenia destrukcji „dobrego” kodu,
nie pogarszasz jakoci kodu,
bd, który wanie poprawiasz, nie pozostanie w innym miejscu
kodu,
nie popenisz w przyszoci tego samego bdu.
Wykorzystuj moliwoci oprogramowania w zakresie demonstracji jego
zachowania.
Nie zajmuj si wieloma problemami jednoczenie.
Upewnij si, e doskonale wiesz:
jak powinna zachowywa si aplikacja?
jak zachowuje si faktycznie?
Poszukujc przyczyn bdów, zaczynaj od rzeczy oczywistych.