Jak cię złapią, to znaczy, że oszukiwałeś. Jak nie, to znaczy, że posłużyłeś się odpowiednią taktyką.
);
ädresowanie za pomocą zerowych wskaźników; ödwołanie do nieprzydzielonych lub zwolnionych obszarów pamięci („błąd A3”, patrz rozdział 3.); ¨ pomyłkowe użycie operatora „$” zamiast „$$”; ¨ błąd pierwszeństwa operatorów; ¨ błędy logiczne. Przywołajmy raz jeszcze błędną instrukcję z rozdziału 1.: & 676 89)% pomyłkowe użycie operatora $ może być tu łatwo przeoczone, jednak zaobserwo- wana zmiana wartości zmiennej wskutek wykonania instrukcji błąd ten natych- miast demaskuje. Podczas pracy krokowej programu zwracaj szczególną uwagę na przepływ danych. CZY CZEGOŚ NIE PRZEOCZYŁEŚ Obserwując przepływ danych podczas pracy krokowej, nie jesteś jednak w stanie wykryć wszystkich błędów. Przyjrzyjmy się poniższemu fragmentowi: : ; ) : 2<" =' ' " )(:> (2'")" ==?(&"2 ':>: *)"2"2): )=?(& @ A 3$ ' @ B' C ' 3$ ' 3$ ' JAK WYKONUJE SIĘ TWÓJ KOD 87 Odwołanie się do pola %&'( ma sens jedynie wtedy, gdy wskaźnik %& jest niezerowy. W instrukcji powinniśmy więc użyć operatora powodu- jącego częściowe wartościowanie koniunkcji (gdy pierwszy jej argument ma war- tość , drugi nie jest już wartościowany), tymczasem użyty operator powo- duje wartościowanie kompletne, co przy zerowej wartości wskaźnika %& może spowodować (a w trybie chronionym — spowoduje na pewno) błąd adresowania. Pomyłkowe użycie operatora nie może jednak zostać wykryte w warunkach kro- kowego śledzenia kodu źródłowego, postrzegającego ów kod w rozbiciu na kom- pletne instrukcje lub linie, nie zaś na poszczególne wyrażenia. Podobnie rzecz się ma z operatorami oraz . A co z optymalizacją przekładu? Wzajemne „dopasowanie” instrukcji kodu źródłowego i rozkazów asemblerowych może być znacznie utrudnione, gdy kompilator dokonuje optymalizacji przekładu. Główne przejawy optymalizacji to eliminacja zbędnego kodu oraz łączne tłumacze- nie kilku sąsiadujących instrukcji kodu źródłowego — czyli zjawiska jak najmniej pożądane w procesie śledzenia kodu. Znakomitą większość kompilatorów można zmusić do poniechania optymalizacji na etapie testowania programu poprzez od- powiednie ustawienie opcji kompilacji, wielu programistów dostrzega w tym jed- nak przejaw nadmiernego różnicowania wersji testowej i handlowej produktu. Sko- ro jednak podstawowym zadaniem testowania jest wyłapanie błędów, warto zastosować każdy zabieg, który może się przyczynić do pomyślnego wykonania te- go zadania. W każdym razie warto zawsze przekonać się, czy dla konkretnego programu optymalizacja istotnie utrudnia śledzenie jego kodu — być może w ogóle nie trzeba będzie jej wyłączać. Poza wyjątkowo dokładnym sprawdzaniem składni wspomnianych instrukcji lub wyświetlaniem wartości poszczególnych wyrażeń (podczas pracy krokowej) jedynym sposobem wykrycia opisanego błędu jest prześledzenie wykonania pro- gramu na poziomie instrukcji asemblera. Wymaga to niewątpliwie kwalifikacji po- trzebnych do skojarzenia rozkazów maszynowych z odpowiadającymi im instruk- cjami kodu źródłowego, jednak takie błędy jak adresowanie z użyciem wyzerowanego rejestru segmentowego stają się natychmiast widoczne. Śledzenie kodu źródłowego musi być niekiedy uzupełnione śledzeniem wygenerowanego przekładu. SPRÓBUJ, A POLUBISZ Niektórych programistów naprawdę trudno skłonić do systematycznego śledzenia własnych programów lub przynajmniej do spróbowania tego przez np. miesiąc. Wymawiają się brakiem czasu, bądź też niechęcią do jego tracenia. Uważam, iż 87 88 NIEZAWODNOŚĆ OPROGRAMOWANIA obowiązkiem każdego kierownika projektu jest przekonanie takich „opornych” pro- gramistów, iż taka oszczędność jest oszczędnością zdecydowanie źle pojętą, gdyż oznacza ryzyko tracenia (w przyszłości) znacznie większej ilości czasu na tropienie błędów w gotowym kodzie, przede wszystkim właśnie za pomocą śledzenia kroko- wego. Myślę, że treść niniejszego rozdziału (jak i pozostałych rozdziałów niniejszej książki) dostarcza niezbędnych ku temu argumentów. Zresztą — jeśli po przełamaniu początkowej niechęci podejmie się próbę śle- dzenia stworzonego właśnie kodu i skonstatuje, że wiele tkwiących w nim błędów można z łatwością wyłapać i usunąć już w ciągu dziesięciu minut, dalsze argu- menty okazują się zbyteczne. W taki oto sposób początkowa nieufność ustępuje miejsca pożytecznym nawykom...
|
Wątki
|