Zajmuję się programowaniem i tworzeniem software’u od 14 lat. Przez te wszystkie lata zawsze najwięcej emocji w mojej pracy dotyczyło błędów. Nie ma oprogramowania bez błędów, chociaż nie wiadomo jak bardzo by się człowiek nie starał. Sztuką jest je usunąć przed publikacją :)

Błędy są różne. O ile w przypadku trywialnych – zazwyczaj nie ma problemu z ich znalezieniem i poprawą – „prawdziwe” błędy mają losową naturę. Najczęściej pierwszy rzut oka wydaje się, że to niemożliwa sytuacja albo, że błąd jest „W systemie operacyjnym”, „W przeglądarce” … W każdym razie  w czymś niezależnym od mojego kodu. Tutaj zła wiadomość – dopóki nie udowodnisz niewinności Twojego kodu, to tam znajduje się błąd. Powiem więcej w 99,9% przypadków błąd jest właśnie w Twoim kodzie.

To złą i dobra wiadomość za razem – zła bo musimy coś poprawić, dobra – bo możemy to poprawić.

Mam takie osobiste spostrzeżenie, że dobrych programistów można odróżnić od tych mniej doświadczonych po tym jak podchodzą do błędu. Dobrzy, doświadczeni programiści zawsze starają się zgromadzić jak najwięcej informacji o błędzie. Jeśli coś wydaje się nielogiczne albo niemożliwe – to znaczy, że masz za mało informacji albo zbyt pobieżnie rozumiesz teorię stojącą za Twoim kodem.

W informatyce zazwyczaj nie ma innych możliwości.

Łatwo poddać się presji i bez dogłębnego zrozumienia przyczyny problemu zastosować obejście. Sam tak bardzo często robiłem (a nawet byłem swego czasu z tego znany :)). Niestety, to się nie sprawdza a takie obejścia powodują zazwyczaj znacznie więcej problemów w dłuższym okresie czasu.

Co można zrobić aby zgromadzić więcej informacji lub lepiej zrozumieć problem?

Czytaj, analizuj kod

Linijka po linijce staraj się ułożyć w głowie przebieg programu i pomyśleć co mogło pójść nie tak. Szczerze? to najlepsza i najprostsza metoda. Wyjście od modelu i teorii do praktyki. Kiedyś razem z Marcinem Engelmannem tworzyliśmy oprogramowanie do transmisji live – oprogramowanie transkodowało w locie obraz wideo z formatu RTMP (FlashMedia) na HTTP (pliki *.flv buforowane w locie). Napisanie oprogramowania zajęło tydzień, doprowadzenie do stabilnego działania 4mc. Program był napisany w C i używał silnie wątków.

Po kilku tygodniach debugowania dyktowanego reagowaniem na objawy – przepisałem kod od zera. Teraz już lepiej rozumiejąc działanie mutextów i wątków W TYM KONKRETNYM przypadku. Dalsze debugowanie było już znacznie prostsze.

Wizualizuj. Rozrysuj sobie używane dane oraz przejścia stanów.

Gromadź informacje

Loguj co tylko można. Pliki logów – serwera, systemu operacyjnego, Twojej aplikacji to podstawowe źródło informacji o błędach. Oprócz logowania możesz korzystać z narzędzi systemowych – np. „strace” albo „gdb”. Używamy ich w Divante nawet do debugowania skryptów PHP. Jeśli nie masz żadnych informacji, te narzędzia są często dobrym punktem startu i drogowskazem.

Rozmawiaj. Wytłumacz problem koledze z pracy. Mogłoby się to wydawać trywialne, ale wcale nie jest – dzięki wyrażeniu zdaniami swoich przypuszczeń możesz zyskać nowy punkt widzenia na sprawę.

Eliminuj. Odrzucaj miejsca, co do których jesteś pewien, że na pewno nie mają błędu. Ale najpierw rozpocznij od swojego kodu, potem dopiero przyglądaj się frameworkowi, następnie kompilatorowi, czy systemowi operacyjnemu itd.

Anegdotka o dobrych praktykach

Na koniec anegdotka o dziwnych obejściach błędów. Kilka – ładnych kilka lat temu – w 2003 roku pracowałem nad edytorem WWW w trybie WYSIWYG o nazwie „WWW Studio 2004”. W czasie prac nad programem, który korzystał z kontrolki do edycji WWW DHTMLEditor (Microsoftu, z tej kontrolki kiedyś korzystały też edytory WYSIWYG na stronach internetowych). Ten edytor był częścią internet explorera. Niestety na Windowsie 98 przy zainstalowanym IE5.5 (i tylko wtedy!) w edytorze nie działało wpisywanie … literki „ł” (małe). Zastosowałem się do wszystkich powyższych zasad ale nie przyniosło to efektu.

Koniec końców rozwiązaniem okazało się obejście którego do dzisiaj się wstydzę, ale które do dzisiaj działa. Program podłączył się pod zdarzenie systemu Windows (tzw. Hook) polegające na obsłudze wciśnięcia przycisku ALT. Program wykrywał czy czasem nie jest wciśnięta też litera l. Jeśli tak, to zapamiętywał aktualną zawartość schowka (:-)) wklejał do schowka znaczek „ł” i następnie wklejał go do okna edytora tam gdzie był kursor. Na koniec przywracał oryginalną zawartość schowka :-)

Pewnie Wy też mieliście ciekawe przejścia z „niemożliwymi” błędami?