Ćwiczenie — debugowanie za pomocą programu Visual Studio
Nadszedł czas, aby przećwiczyć nowo zdobytą wiedzę na temat debugowania. To twój pierwszy dzień w pracy i chcesz wykorzystać swoje umiejętności debugowania na platformie .NET, aby naprawić usterkę w flagowym produkcie firmy, którym jest kalkulator Fibonacciego.
Tworzenie przykładowego projektu platformy .NET na potrzeby debugowania
Aby skonfigurować debugowanie programu Visual Studio dla platformy .NET, najpierw potrzebujemy projektu platformy .NET. Program Visual Studio udostępnia mnóstwo szablonów startowych, które ułatwiają tworzenie nowego projektu.
W programie Visual Studio wybierz pozycje Plik>Nowy>Projekt.
W oknie dialogowym Tworzenie nowego projektu wybierz pozycję Aplikacja konsolowa, a następnie wybierz pozycję Dalej.
Nadaj projektowi nazwę DotNetDebugging i wybierz lokalizację, w której chcesz zapisać. Pozostaw wartości domyślne pozostałych, a następnie wybierz pozycję Dalej.
Wybierz pozycję Utwórz na ekranie końcowym.
Program Visual Studio tworzy dla nas projekt Konsoli przy użyciu wybranego szablonu. Po załadowaniu projektu otwórz Program.cs , wybierając go.
Dodawanie logiki programu Fibonacciego
Nasz bieżący projekt wypisuje w konsoli komunikat „Hello World”, co nie dostarcza nam zbyt wielu danych do debugowania. Zamiast tego użyjemy krótkiego programu .NET, aby obliczyć Nnumer sekwencji Fibonacciego.
Ciąg Fibonacciego to zbiór liczb rozpoczynający się od cyfr 0 i 1, przy czym każda kolejna liczba jest sumą dwóch poprzednich. Sekwencja będzie wyglądać następująco:
0, 1, 1, 2, 3, 5, 8, 13, 21...
Poniższy przykładowy kod zawiera usterkę, więc użyjemy narzędzi debugowania programu Visual Studio, aby zdiagnozować i rozwiązać ten problem.
- Zastąp zawartość pliku Program.cs następującym kodem:
int result = Fibonacci(5);
Console.WriteLine(result);
static int Fibonacci(int n)
{
Console.WriteLine("The output is: ");
int n1 = 0;
int n2 = 1;
int sum;
for (int i = 2; i < n; i++)
{
sum = n1 + n2;
n1 = n2;
n2 = sum;
}
return n == 0 ? n1 : n2;
}
Uwaga
Ten kod zawiera błąd, który naprawiamy w dalszej części tego modułu. Nie zaleca się używania go w żadnej aplikacji Fibonacciego o znaczeniu krytycznym, dopóki ta usterka nie zostanie naprawiona.
Zapisz plik za pomocą Ctrl+S dla systemów Windows i Linux. Na komputerach Mac wybierz klawisze Cmd+S.
Przyjrzyjmy się, jak działa zaktualizowany kod przed jego zdebugowaniem. Uruchom program, naciskając zielony przycisk startowy na pasku poleceń programu Visual Studio.
Na końcu danych wyjściowych konsoli debugowania widać, że program wypisuje 3 na konsolę, a następnie kończy działanie z kodem 0. Zazwyczaj kod zakończenia programu 0 wskazuje, że program został uruchomiony i zakończony bez awarii. Istnieje jednak różnica między awarią i zwróceniem poprawnej wartości.
W tym przypadku poprosiliśmy program, aby obliczał piątą wartość sekwencji Fibonacciego:
0, 1, 1, 2, 3, 5, 8, 13, 21...
Piąta wartość na tej liście to 5, ale nasz program zwrócił wartość 3. Użyjmy debugera, aby zdiagnozować i usunąć ten błąd.
Użyj punktów przerwania i wykonuj krok po kroku
Dodaj punkt przerwania, klikając w lewym marginesie przy linii 1 na
int result = Fibonacci(5);.Ponownie uruchom debugowanie. Program zaczyna się wykonywać. Przerywa (wstrzymuje wykonywanie) w wierszu 1 ze względu na ustawiony punkt przerwania. Użyj kontrolek debugera, aby przejść do funkcji
Fibonacci().
Sprawdzanie stanu zmiennych
Teraz poświęć trochę czasu, aby sprawdzić wartości różnych zmiennych, korzystając z okna Zmienne lokalne.
- Jaka jest pokazana wartość parametru
n? - Jakie są wartości zmiennych lokalnych
n1,n2isumna początku wykonywania funkcji?
Następnie przechodzimy do pętli przy użyciu kontrolki
forDebuger krok po kroku.
Kontynuuj przechodzenie, aż osiągniesz pierwszy wiersz w pętli
for. Linia, która brzmi:sum = n1 + n2;
Uwaga
Możesz zauważyć, że przejście przez linię for(...) {} wymaga wykonania kilku kroków polegających na wprowadzaniu różnych poleceń. Sytuacja ta występuje, ponieważ w tym wierszu znajduje się wiele instrukcji. Gdy wykonasz krok, przechodzisz do następnej instrukcji w kodzie. Zazwyczaj jest jedno wyrażenie na wiersz. Jeśli to nie jest prawda, musisz wykonać wiele kroków, aby przejść do następnego wiersza.
Myśl o kodzie
Ważną częścią debugowania jest zatrzymanie się i zastanowienie się nad tym, co Twoim zdaniem próbują zrobić fragmenty kodu (funkcje i bloki, takie jak pętle). Jeśli nie masz pewności, nie ma problemu — jest to część procesu debugowania. Jednak aktywne zaangażowanie w proces debugowania ułatwia szybsze lokalizowanie usterek.
Przed zapoznaniem się z dalszymi szczegółami przypomnijmy, że ciąg Fibonacciego to seria liczb rozpoczynająca się od cyfr 0 i 1, w którym każda kolejna liczba jest sumą dwóch poprzednich.
Oznacza to, że:
Fibonacci(0) = 0
Fibonacci(1) = 1
Fibonacci(2) = 1 (0 + 1)
Fibonacci(3) = 2 (1 + 1)
Fibonacci(4) = 3 (1 + 2)
Fibonacci(5) = 5 (2 + 3)
Jeśli rozumiemy tę definicję i przyjrzymy się pętli for, możemy wydedukować, że:
- Pętla liczy od 2 do
n(liczba ciągu Fibonacciego, której szukamy). - Jeśli
nwartość jest mniejsza niż 2, pętla nigdy nie jest uruchamiana. Instrukcjareturnna końcu funkcji zwraca wartość 0, jeślinma wartość 0, i 1, jeślinma wartość 1 lub 2. Te wartości to wartości zero, pierwsze i drugie w serii Fibonacciego według definicji. - Bardziej interesujący przypadek występuje, gdy wartość
njest większa niż 2. W takich przypadkach bieżąca wartość jest definiowana jako suma dwóch poprzednich wartości. Dla tej pętlin1in2są dwiema poprzednimi wartościami, asumjest wartością dla bieżącej iteracji. Ze względu na tę logikę za każdym razem, gdy obliczamy sumę poprzednich dwóch wartości i ustawiamy ją nasum, aktualizujemy naszen1wartości in2.
W porządku, dalej nie musimy się zbytnio w to zagłębiać. Możemy w pewnym stopniu polegać na naszym debugerze. Warto jednak zastanowić się nad kodem, aby sprawdzić, czy robi to, czego oczekujemy, i wiedzieć, co zrobić, jeśli kod nie zachowuje się zgodnie z oczekiwaniami.
Zlokalizuj usterkę za pomocą punktów przerwania
Przechodzenie przez kod może być przydatne, ale może być również żmudne. Szczególnie w przypadku pracy z pętlami lub innym kodem, który jest wywoływany wielokrotnie. Zamiast wiele razy przechodzić przez pętlę, można ustawić nowy punkt przerwania w pierwszym wierszu pętli.
Ważne jest, aby podejść strategicznie do umieszczania naszych punktów podziału. Jesteśmy szczególnie zainteresowani wartością sum, ponieważ reprezentuje bieżącą maksymalną wartość ciągu Fibonacciego. Dlatego umieśćmy nasz punkt przerwania w wierszu posum ustawieniu.
Dodaj drugi punkt przerwania w wierszu 14.
Uwaga
Jeśli zauważysz, że nadal uruchamiasz swój kod, a następnie przechodzisz przez jeden lub dwa wiersze, możesz łatwo zaktualizować punkty przerwania do efektywniejszych wierszy.
Teraz, gdy mamy dobry punkt przerwania ustawiony w pętli, wybierz pozycję Kontynuuj w kontrolkach debugera, aby przejść do momentu osiągnięcia punktu przerwania. Patrząc na nasze zmienne lokalne, zobaczymy następujące wiersze:
n [int]: 5 n1 [int]: 0 n2 [int]: 1 sum [int]: 1 i [int]: 2Wszystkie te wiersze wydają się być poprawne. Podczas pierwszego przejścia przez pętlę element
sumdla poprzednich dwóch wartości wynosi 1. Zamiast krokowo przechodzić przez kolejne wiersze, możemy skorzystać z naszych punktów przerwania, aby przenieść się do kolejnego przebiegu pętli.Wybierz pozycję Kontynuuj, aby kontynuować przepływ programu do momentu, gdy zostanie trafiony następny punkt przerwania, czyli podczas następnego przejścia przez pętlę.
Uwaga
Nie martw się zbytnio o pominięcie usterki, gdy używasz Kontynuuj. Należy się spodziewać, że możesz debugować za pomocą kodu kilka razy, aby znaleźć problem. Często szybciej jest przejść przez coś kilka razy niż być zbyt ostrożnym za pierwszym razem.
Tym razem zobaczysz następujące wartości:
n [int]: 5 n1 [int]: 1 n2 [int]: 1 sum [int]: 2 i [int]: 3Czy te wartości nadal mają sens? Wygląda na to, że tak. W przypadku trzeciej liczby ciągu Fibonacciego oczekujemy, że nasz element
sumbędzie mieć wartość 2, i faktycznie tak jest.Wybierz pozycję Kontynuuj, aby zapętlić ją ponownie.
n [int]: 5 n1 [int]: 1 n2 [int]: 2 sum [int]: 3 i [int]: 4Wynik jest poprawny. Czwarta wartość w serii powinna wynosić 3.
W tym momencie można zacząć się zastanawiać, czy może kod był przez cały czas prawidłowy, a usterka powstała tylko w Twojej wyobraźni! Przejdźmy po raz ostatni przez pętlę. Wybierz pozycję Kontynuuj jeszcze jeden raz.
Program zakończył działanie, a dane wyjściowe to 3! Nasz wynik jest niepoprawny.
Wiemy teraz, że kod przechodzi przez pętlę prawidłowo do momentu, gdy wartość
ijest równa 4, ale następnie kończy działanie przed obliczeniem końcowej wartości. Zawęziliśmy miejsce, w którym znajduje się usterka.Ustawmy jeszcze jeden punkt przerwania w wierszu 18, który brzmi:
return n == 0 ? n1 : n2;Ten punkt przerwania pozwala nam sprawdzić stan programu przed zamknięciem funkcji. Dowiedzieliśmy się już wszystkiego, czego można się spodziewać po naszych poprzednich punktach przerwania na liniach 1 i 13, więc możemy je usunąć.
Usuń poprzednie punkty przerwania w wierszach 1 i 13. Zaznacz punkty przerwania na marginesie obok numerów wierszy lub wyczyść pola wyboru punktu przerwania dla wierszy 1 i 13 w okienku punktów przerwania w lewym dolnym rogu.
Teraz, gdy lepiej zrozumieliśmy, co się dzieje, możemy ustawić punkt przerwania zaprojektowany, aby przyłapać nasz program na błędnym działaniu. Teraz powinniśmy być w stanie złapać tę usterkę!
Uruchom debugera po raz ostatni.
n [int]: 5 n1 [int]: 2 n2 [int]: 3 sum [int]: 3Specjalnie poprosiliśmy o Fibonacciego(5), a otrzymaliśmy Fibonacciego(4), co jest niepoprawne. Ta funkcja zwraca wartość
n2, a każda iteracja pętli oblicza wartośćsumi ustawia elementn2równysum.Na podstawie tych informacji i poprzedniego przebiegu debugowania możemy zobaczyć, że pętla zakończyła się, gdy element
imiał wartość 4, a nie 5.Przyjrzyjmy się bliżej naszej
forpętli.for (int i = 2; i < n; i++)Ta logika powoduje, że program zakończy działanie, gdy tylko początek pętli for porówna
idon. Oznacza to, że kod pętli nie jest uruchamiany w przypadku, gdyijest równan. Wygląda na to, że w zamian chcieliśmy uruchomić kod doi <= n:for (int i = 2; i <= n; i++)W związku z tym zaktualizowany program powinien wyglądać tak jak w tym przykładzie:
int result = Fibonacci(5); Console.WriteLine(result); static int Fibonacci(int n) { Console.WriteLine("The output is: "); int n1 = 0; int n2 = 1; int sum; for (int i = 2; i <= n; i++) { sum = n1 + n2; n1 = n2; n2 = sum; } return n == 0 ? n1 : n2; }Zatrzymaj sesję debugowania, jeśli jeszcze tego nie zrobiono.
Wprowadź poprzednią zmianę w wierszu 11 i pozostaw punkt przerwania w wierszu 18.
Uruchom ponownie debuger. Tym razem po osiągnięciu punktu przerwania w wierszu 18 zobaczymy następujące wartości:
n [int]: 5 n1 [int]: 3 n2 [int]: 5 sum [int]: 5Hej! Wygląda na to, że to mamy! Świetna robota, uratowałeś dzień dla Fibonacciego, Inc.!
Wybierz pozycję Kontynuuj, aby upewnić się, że program zwraca poprawną wartość.
5 The program '[105260] DotNetDebugging.dll' has exited with code 0 (0x0).To zwraca prawidłowy wynik.
Udało Ci się! Debugowałeś kod, którego nie napisałeś, używając debugera platformy .NET w programie Visual Studio.
W następnej lekcji dowiesz się, jak ułatwić debugowanie kodu przy użyciu funkcji rejestrowania i śledzenia wbudowanych w platformę .NET.