Nowoczesne debugery zawierają jeszcze jedno okno informacji o debugowaniu, które może być bardzo przydatne w debugowaniu programu, a jest nim stos wywołań okno.
Kiedy Twój program wywołuje funkcję, już wiesz, że dodaje do zakładek bieżącą lokalizację, wywołuje funkcję i następnie wraca. Skąd wie, dokąd wrócić? Odpowiedź jest taka, że śledzi stos wywołań.
Klasa stos wywołań to lista wszystkich aktywnych funkcji, które zostały wywołane, aby dostać się do bieżącego punktu wykonania. Stos wywołań zawiera wpis dla każdej wywoływanej funkcji, a także wiersz kodu, do którego zostanie zwrócony, gdy funkcja powróci. Za każdym razem, gdy wywoływana jest nowa funkcja, jest ona dodawana na górę stosu wywołań. Kiedy bieżąca funkcja powraca do wywołującego, jest ona usuwana ze szczytu stosu wywołań, a sterowanie powraca do funkcji znajdującej się tuż pod nią.
Klasa Okno stosu wywołań to okno debugera, które pokazuje bieżący stos wywołań. Jeśli nie widzisz okna stosu wywołań, musisz poinformować IDE, aby je pokazało.
W przypadku użytkowników programu Visual Studio
W Visual Studio okno stosu wywołań można znaleźć poprzez menu debugowania > Windows > Stos wywołań. Pamiętaj, że aby aktywować to okno, musisz być w sesji debugowania.
W przypadku użytkowników Code::Blocks
W Code::Blocks okno stosu wywołań można znaleźć poprzez Menu debugowania > Okna debugowania > Stos wywołań.
Dla użytkowników VS Code
W VS Code okno stosu wywołań pojawia się w trybie debugowania, zadokowane po lewej stronie.
Przyjrzyjmy się stosowi wywołań na przykładzie program:
#include <iostream>
void a()
{
std::cout << "a() called\n";
}
void b()
{
std::cout << "b() called\n";
a();
}
int main()
{
a();
b();
return 0;
}Umieść punkty przerwania w liniach 5 i 10 tego programu, a następnie rozpocznij tryb debugowania. Ponieważ funkcja a jest wywoływana jako pierwsza, jako pierwszy zostanie trafiony punkt przerwania w linii 5.
W tym momencie powinieneś zobaczyć coś takiego:

Twoje IDE może wykazywać pewne różnice:
- Format nazw funkcji i numerów linii może być inny
- Twoje numery linii mogą się nieznacznie różnić (wyłączone przez 1)
- Zamiast [Kod zewnętrzny] możesz zobaczyć kilka innych dziwnie nazwanych funkcji.
Te różnice są nieistotne.
Istotne są tutaj dwie górne linie. Patrząc od dołu do góry, widzimy, że funkcja głównego została wywołana jako pierwsza, a następnie ta funkcja a została wywołana jako następna.
Klasa linia 5 obok funkcji a pokazuje nam, gdzie znajduje się bieżący punkt wykonania (który odpowiada znacznikowi wykonania w oknie kodu). Linia 17 w drugiej linii wskazuje linię, do której zostanie zwrócony, gdy sterowanie powróci do funkcji. głównego.
Wskazówka
Numery linii po nazwach funkcji wskazują następną linię do wykonania w każdej funkcji.
Ponieważ górna pozycja na stosie wywołań reprezentuje aktualnie wykonywaną funkcję, numer linii tutaj wskazuje następną linię, która zostanie wykonana po wznowieniu wykonywania. Pozostałe wpisy na stosie wywołań reprezentują funkcje, do których w pewnym momencie zostaną zwrócone, więc numery ich wierszy reprezentują następną instrukcję, która zostanie wykonana po zwróceniu funkcji.
Teraz wybierz polecenie Kontynuować polecenie debug, aby przejść do następnego punktu przerwania, który będzie w linii 10. Stos wywołań powinien zostać zaktualizowany, aby odzwierciedlić nową sytuację:

Zauważysz, że funkcja b jest teraz górną linią stosu wywołań, co odzwierciedla fakt, że funkcja b jest funkcją, która jest aktywnie wykonywana. Należy zauważyć, że funkcja a nie jest już reprezentowana na stosie wywołań. Dzieje się tak, ponieważ funkcja a została usunięta ze stosu wywołań po jej zwróceniu.
Wybierz jeszcze raz polecenie Kontynuować debug, a ponownie trafimy na punkt przerwania w linii 5 (ponieważ funkcja b wywołuje funkcję a). Stos wywołań będzie wyglądał następująco:

Na stosie wywołań znajdują się teraz trzy funkcje: (od dołu do góry) głównego, która wywołała funkcję b, która wywołała funkcję a.
Stos wywołań jest przydatny w połączeniu z punktami przerwania, gdy punkt przerwania zostanie trafiony i chcesz wiedzieć, jakie funkcje zostały wywołane, aby dostać się do tego konkretnego punktu w kodzie.
Wnioski
Gratulacje, znasz teraz podstawy korzystania ze zintegrowanego debuger! Używając kroków, punktów przerwania, zegarków i okna stosu wywołań, masz teraz podstawy umożliwiające debugowanie prawie każdego problemu. Podobnie jak w przypadku wielu innych rzeczy, nabycie umiejętności posługiwania się debugerem wymaga pewnej praktyki oraz prób i błędów. Ale jeszcze raz powtórzymy, że czas poświęcony na naukę efektywnego korzystania ze zintegrowanego debugera zwróci się wielokrotnie w czasie zaoszczędzonym na debugowaniu programów!

