Debugowanie

Proces wyszukiwania i usuwania błędów w kodzie. Często wspierany przez narzędzia pozwalające śledzić wykonanie programu krok po kroku.

Debugowanie to proces lokalizowania, analizowania i usuwania błędów (tzw. bugów) w kodzie — czyli wszystkiego, co sprawia, że program działa inaczej, niż zaplanowałeś. To nie tylko „naprawianie”, ale przede wszystkim dochodzenie do przyczyny: dlaczego aplikacja się wykrasza, zwraca zły wynik albo milczy, choć powinna coś zrobić. Nazwa pochodzi od anegdoty o ćmie (ang. bug), która w 1947 roku utknęła w przekaźniku komputera Harvard Mark II — Grace Hopper wkleiła ją do dziennika z podpisem „first actual case of bug being found”.

Jak to działa

Debugowanie polega na zawężaniu obszaru, w którym kryje się błąd. Zaczynasz od objawu (np. wyjątek, zła wartość), formułujesz hipotezę, gdzie leży problem, i sprawdzasz ją — podglądając stan programu w trakcie wykonania. Kluczowe narzędzie to debugger, który pozwala zatrzymać program w wybranym miejscu (breakpoint), wykonywać kod krok po kroku, podejrzeć wartości zmiennych i prześledzić stos wywołań (call stack).

W praktyce łączysz kilka technik: czytanie logów, ustawianie breakpointów, czasem dobre stare wypisywanie zmiennych na ekran. Każda z nich służy temu samemu: zobaczyć, co program naprawdę robi, a nie co Ci się wydaje, że robi.

Przykład z praktyki

Załóżmy, że masz aplikację w Pythonie, która wywala się przy przetwarzaniu listy. Zamiast zasypywać kod print(), wstawiasz w podejrzanym miejscu breakpoint() (wbudowane od Pythona 3.7). Program zatrzyma się w interaktywnym debuggerze pdb, gdzie wpiszesz p moja_zmienna, by zobaczyć jej wartość, n (next), by przejść do kolejnej linii, albo c (continue), by jechać dalej. W programach w C/C++ tę samą robotę odwala gdb, a w przeglądarce — DevTools (zakładka Sources). Większość IDE, jak VS Code czy PyCharm, daje to wszystko klikalnie.

Częste błędy i mity

  • „Debuguję, więc dodaję printy wszędzie” — działa, ale debugger jest szybszy i nie zostawia śmieci w kodzie. Printy potrafią zostać w repo na lata.
  • Zgadywanie zamiast mierzenia — nie zmieniaj losowo linijek, licząc, że „samo się naprawi”. Najpierw odtwórz błąd w sposób powtarzalny.
  • Mit „to działa na moim komputerze” — różnice środowisk (wersje, dane, zmienne środowiskowe) to klasyczne źródło bugów, które trudno powtórzyć.
  • Heisenbug — błąd, który znika, gdy próbujesz go obserwować. Często wynika z problemów z czasem wykonania albo współbieżnością.

Pojęcia powiązane: breakpoint, stack trace, logowanie, testy jednostkowe, wyjątek (exception), profilowanie oraz kontrola wersji, dzięki której łatwiej znaleźć commit, który wprowadził błąd (np. git bisect).