Początki debugowania...
01.02.2012 | aktual.: 02.02.2012 14:18
Dzisiaj będzie troszkę o debugowaniu w NetBeans.
Trochę torii na początek. Debugowaniem nazywamy proces śledzenia wykonywania programu, inaczej mówiąc kontrolowanie i sprawdzanie wykonania programu. Jeszcze prościej?! Śledzenie wykonywania programu krok po kroku, linijka po linijce, instrukcja po instrukcji, sprawdzając przy tym stan obiektów, zmiennych etc. - jaśniej już nie potrafię ;] Celem debugowania jest rozpoznanie błędu w programie, znalezienie miejsca i przyczyny, a następnie usunięcie go. Na końcu znowu należałoby przetestować, czy wyeliminowano błąd i czy nie wytworzyło się nowego(czasami się zdarza ;)). Czyni się to przy użyciu debuggera.
Co to jest debugger? Jest to nic innego jak program komputerowy służący do analizy innych programów (przynajmniej tak twierdzi wiki ), w celu znalezienia i wyeliminowania błędów. Program ten sprawuje kontrolę nad wykonaniem kodu tworzonego przez nas programu. Pozwala na śledzenie obiektów, atrybutów i kontrolowanie wykonania programu( tak jak odtwarzacz muzyczny :P „Play”, „Pause”, „Stop” itp. - przynajmniej taki debugger znam w NetBeans).
Kiedy stosujemy debugowanie? Ja stosuje wtedy, gdy stwierdzę, że program działa niepoprawnie i nie wiem co jest przyczyną. Co debuguję? - zazwyczaj jedynie podejrzane fragmenty programu (nie ma sensu debugowania całego programu, skoro błąd występuje w pewnej funkcji -funkcjonalności). Co sprawdzam? - stan obiektów, atrybutów, referencje do obiektów oraz jak się zmieniają i wypatruję miejsca, w którym obiekt (atrybut) lub referencja przyjmuje niepoprawną stan lub wartość. Kiedy najtrudniej znaleźć błąd – osobiście najtrudniej mi znaleźć błąd jeżeli jest on banalny, mały a wywołuje dużą zmianę w działaniu. Także, gdy program współdziała z innymi programami, wymienia dane itp., oraz w programach współbieżnych i rozproszonych – hardcore!!
Ok. Teraz pora uruchomić NetBeans ;] Gdy już uruchomimy, należy utworzyć nowy projekt, żeby móc na czymś przedstawić sposób debugowania. Wybieramy aplikacje konsolową. Nasz prosty przykład ma za zadanie wypisać z tablicy elementy będące liczbami parzystymi. A więc tworzymy program tak jak to zostało pokazane na rysunku poniżej.
Jak widać program zawiera błąd i się zawiesza ;] Nie popisałem się inwencją twórczą, ale to jest przykład i ma pokazać jak się debuguje :P ;]
A więc w miejscu gdzie podejrzewamy, że występuje „bug” zastawiamy pułapki – klikamy lewym przyciskiem myszy na nr linijki( zaprezentowano na rysunku poniżej), a linijka zostaje oznaczona kolorem różowym (nie będę się spierał czy jest to łososiowy czy też brzoskwiniowy).
W oznaczonych w ten sposób miejscach (nazywanych pułapkami) program zatrzyma się.
Śledzenie obiektów, atrybutów, zmiennych!! Aby śledzić stan obiektów i atrybutów trzeba zaznaczyć nazwę atrybutu lub obiektu, kliknąć prawym klawiszem i z menu konteksowego wybrać „New watch” lub użyć skrótu klawiaturowego Ctrl+Shift+F7.
Wyświetli nam się okno, w którym wprowadzamy nazwę.
Po zatwierdzeniu otworzy nam się nowy panel o nazwie „Variables”, w którym będziemy śledzić stan naszej zmiennej „i”.
No to pora odpalać debugowanie. Służy do tego przycisk pokazany na poniższym zrzucie lub skrót Ctrl+F5.
Program zatrzymał się przed wykonaniem pierwszego cyklu pętli while, a nasza zmienna i ma wartość 0 (pokazane na zrzucie poniżej). a więc teraz wykorzystamy przycisk przejścia do następnej pułapki (o ile jest ona zastawiona – u nas jest w linijce 23). Służy do tego przycisk „Play” :P koloru zielonego. Po jego naciśnięciu zatrzymamy się przed instrukcją zwiększającą wartość i o jeden. Do wykonywania kodu mamy kilka możliwości. Możemy wykonać jedną instrukcję, jedną linijkę programu, ale możemy również wejść do kodu metody i wykonywać jej instrukcje, powrócić z kodu metody, do programu lub przejść do linijki w której umieszczony jest kursor.
Poniżej przedstawiono przyciski:
1 – „Finish” (Shift+F5)- zatrzymanie procesu debugowania; 2 – „Pause” - przerwa w procesie debugowania, np. podczas wykonywania długich pętli lub operacji; 3 – „Continue”(F5) - wykonanie do następnej pułapki lub zakończenia się programu; 4 - „Step Over” (F8)- wykonanie następnej instrukcji; 5 - „Step Over Expression” (Shift+F8)- wykonanie następnej instrukcji po wyrażeniu; 6 - „Step Into” (F7)- wejście do metody; 7 - „Step Out” (Ctrl+F7)- wyjście z metody; 8 – „Run To Cursor” (F4)- przejście do linijki, gdzie umieszczony jest kursor.
Tyle nam wystarczy, aby mieć kontrolę nad wykonaniem programu i mieć możliwość śledzenia zmian w programie. Przycisk 6, 7 można przetestować na metodzie „println”. Akcja związana z przycikiem 8 działa jedynie jeżeli kursor jest umieszczony w linijce, która ma się wykonać (raczej nie da się zmienić biegu wykonania programu tymi przyciskami, aczkolwiek możemy panować nad czasem ;).
Podczas debugowania możemy również dodawać do obserwowanych nowe obiekty i sprawdzać ich stan.
Śledząc wykonanie programu widzimy, że instrukcja „i++;” wykona się tylko raz, i będzie miało wartość 1, a pętla się nie skończy. Należy usunąć blok „else{}”, a instrukcję inkrementacji przenieść do bloku pętli.
Podczas debugowania możemy sprawdzać o wiele więcej niż przedstawiony tutaj przykład. Są to między innymi stos wywołań, śledzić wykonanie wątków, sesje, załadowane klasy...
Polecam również stworzyć jakiś przykład z wątkami, w których zachodzi synchronizacja.
Uważam, że najlepszą metodą nauki jest uczenie się na błędach :P i debugowanie ;], zatem uczcie się, na większych i mniejszych projektach...
Jakość przede wszystkim ;]