RSS

Nie ufaj debuggerom

Liczba odsłon: 26

Szukałem dzisiaj błędu w programie: macierz, która wydawała się całkiem poprawna gdy zapisywałem ją do pliku, wypisana chwilę później na ekranie miała już zmodyfikowanych parę elementów. Co gorsza, kolejność, z którą zapisywane były elementy macierzy, zdawała się mieć wpływ na to, czy „sporne” elementy macierzy były zerowane czy nie.

Podejrzewałem wewnętrzny błąd mojej klasy C++ obsługującej macierze rzadkie, zacząłem zatem przeglądać wątpliwy fragment kodu za pomocą programu uruchomieniowego (debuggera) wbudowanego w Visual C++ Express. Początkowo potwierdziło to moje najgorsze obawy: wydawało się, że z jakichś niewyjaśnionych przyczyn indeksy macierzy nie są prawidłowo przekształcane, przez co odczytywane są niewłaściwe komórki. Tego typu błędy są tragiczne: poprawny kod nie jest wykonywany poprawnie na skutek jakichś wcześniejszych, samych w sobie nie katastrofalnych usterek. Kilkanaście minut spędzonych nad programem utwierdziło mnie jednak w przekonaniu, że klasa działa najzupełniej poprawnie. To debugger nie aktualizował wyświetlanych w oknie podglądu wartości zmiennych! Z sobie tylko znanych przyczyn wykrywał zmiany w niektórych zmiennych, inne – ewidentnie modyfikowane – ignorując.

W końcu okazało się, że błąd polegał po prostu na... wywołaniu procedury obliczeniowej modyfikującej macierz. Zmiana kolejności kodu usunęła wątpliwości co do prawidłowego przechowywania danych w macierzy. Pozostała jednak nauczka, by nigdy bezkrytycznie nie wierzyć programom uruchomienionym — mimo, iż często bywają tak niesamowicie użyteczne.


Problem, który opisujesz jest dość częsty. Programista z uporem maniaka twierdzi, że jakaś część kodu zwykle jedna funkcja jest poprawna. Wtedy nawet "zwala" winę na debuggera, że źle pokazuje. W takiej sytuacji trzeba przeanalizować dokładnie kod wcześniejszy mimo, że wydaje się nam, iż błąd jest w funkcji, nad którą siedzimy. W 100% przypadków okazuje się że debugger pokazuje dobrze a wina leży w kodzie wcześniejszym niż analizujemy. Taki też przypadek Ty opisałeś.
E e. Nie zrozumiałeś. Kod był faktycznie dobry. Nawet po tej poprawce debugger nie pokazywał zmian wartości zmiennych, które faktycznie się zmieniały. Po prostu nie wykrywał, że program coś zapisuje w tych zmiennych.
To proszę mi wysłać ten kod i zaznaczyć w której linijce jest źle.
Kod wyglądał następująco:
--row;
a debugger po krokowym przejściu przez ten wiersz nie aktualizował wyświetlanej na dole wartości row mimo, że printf() przed i po tym wierszu odnotowywał zmianę.
Chciałbym dostać cały kod tego programu a nie jedną linijkę kodu :)
A próbował Pan w różnych Debuggerach? Ja bym temu od M$ nie wierzył i tak i tak, bo nie jest jedyny.
Całego kodu nie mogę udostępnić. Innych debuggerów nie próbowałem, program powstaje jak na razie w Visual Studio. Poza tym sprawa była jednorazowa, program po znalezieniu błędu w wywołaniu działa już dobrze niezależnie od tego, co pokazywał debugger.