Udostępnij przez


Zmienianie kontekstów

W debugowaniu w trybie jądra istnieje wiele procesów, wątków, a czasami sesji użytkownika, które są wykonywane w tym samym czasie. W związku z tym frazy takie jak "wirtualny adres 0x80002000" lub "rejestr eax " są niejednoznaczne. Należy określić kontekst , w którym można zrozumieć takie frazy.

Debuger ma pięć różnych kontekstów, które można ustawić podczas debugowania:

  1. Kontekst sesji wskazuje domyślną sesję użytkownika.

  2. Kontekst procesu określa, jak debuger interpretuje adresy wirtualne.

  3. Kontekst adresu trybu użytkownika prawie nigdy nie jest ustawiany bezpośrednio. Ten kontekst jest ustawiany automatycznie podczas zmieniania kontekstu procesu.

  4. Kontekst rejestru określa, jak debuger interpretuje rejestry, a także kontroluje wyniki śledzenia stosu. Ten kontekst jest również znany jako kontekst wątku, chociaż ten termin nie jest całkowicie dokładny. Jawny kontekst jest również typem kontekstu rejestru. Jeśli określisz jawny kontekst, ten kontekst jest używany zamiast bieżącego kontekstu rejestru.

  5. Kontekst lokalny określa, jak debuger interpretuje zmienne lokalne. Ten kontekst jest również nazywany zakresem.

Kontekst sesji

W tym samym czasie można uruchomić wiele sesji logowania. Każda sesja logowania ma własne procesy.

Rozszerzenie !sesji wyświetla wszystkie sesje logowania lub zmienia kontekst bieżącej sesji.

Kontekst sesji jest używany przez !sprocess i !spoolused rozszerzeń, gdy numer sesji jest wprowadzany jako "-2".

Po zmianie kontekstu sesji kontekst procesu zostanie automatycznie zmieniony na aktywny proces dla tej sesji.

Kontekst procesu

Każdy proces ma własny katalog stron, który rejestruje sposób mapowania adresów wirtualnych na adresy fizyczne. Gdy dowolny wątek w procesie jest wykonywany, system operacyjny Windows używa tego katalogu strony do interpretowania adresów wirtualnych.

Podczas debugowania w trybie użytkownika bieżący proces określa kontekst procesu. Adresy wirtualne używane w poleceniach debugera, rozszerzeniach i oknach informacji debugowania są interpretowane przy użyciu katalogu strony bieżącego procesu.

Podczas debugowania w trybie jądra można ustawić kontekst procesu przy użyciu polecenia .process (Ustaw kontekst procesu). Użyj tego polecenia, aby wybrać katalog stron procesu używany do interpretowania adresów wirtualnych. Po ustawieniu kontekstu procesu można użyć tego kontekstu w dowolnym poleceniu, które przyjmuje adresy. Możesz nawet ustawić punkty przerwania pod tym adresem. Włączając opcję /i w poleceniu .process, aby określić inwazyjne debugowanie, można również użyć debugera jądra do ustawienia punktów przerwania w przestrzeni użytkownika.

Punkty przerwania trybu użytkownika można również ustawić z debugera jądra, używając punktu przerwania specyficznego dla procesu w funkcji przestrzeni jądra. Ustaw strategiczne punkty przerwania i poczekaj, aż pojawi się odpowiedni kontekst.

Kontekst adresu trybu użytkownika jest częścią kontekstu procesu. Zazwyczaj nie trzeba samodzielnie ustawiać kontekstu adresu trybu użytkownika. Jeśli ustawisz kontekst procesu, kontekst adresu w trybie użytkownika automatycznie zmieni się na bazę katalogową odpowiedniej tabeli stron dla procesu.

Po ustawieniu kontekstu procesu podczas debugowania w trybie jądra kontekst procesu jest zachowywany do momentu zmiany kontekstu przez inne polecenie procesu . Kontekst adresu trybu użytkownika jest również zachowywany do momentu zmiany polecenia .process lub .context . Te konteksty nie są zmieniane, gdy komputer docelowy wykonuje operacje, i nie są także zależne od zmian kontekstu rejestru ani kontekstu lokalnego.

Rejestrowanie kontekstu

Każdy wątek ma własne wartości rejestru. Te wartości są przechowywane w rejestrach procesora CPU, gdy wątek jest wykonywany i są przechowywane w pamięci podczas wykonywania innego wątku.

Podczas debugowania w trybie użytkownika bieżący wątek zwykle określa kontekst rejestru. Wszelkie odwołania do rejestrów w poleceniach debugera, rozszerzeniach i oknach informacji debugowania są interpretowane zgodnie z rejestrami bieżącego wątku.

Kontekst rejestru można zmienić na wartość inną niż bieżący wątek podczas debugowania w trybie użytkownika przy użyciu jednego z następujących poleceń:

.cxr (Wyświetl rekord kontekstu)

.ecxr (Wyświetl rekord kontekstu wyjątku)

Podczas debugowania w trybie jądra można kontrolować kontekst rejestru przy użyciu różnych poleceń debugera, w tym następujących poleceń:

.thread (Ustaw kontekst rejestru)

.cxr (Wyświetl rekord kontekstu)

.trap (Wyświetl ramkę pułapki)

Te polecenia nie zmieniają wartości rejestrów procesora CPU. Zamiast tego debuger pobiera określony kontekst rejestru z jego lokalizacji w pamięci. W rzeczywistości debuger może pobrać tylko zapisane wartości rejestru. (Inne wartości są ustawiane dynamicznie i nie są zapisywane. Zapisane wartości są wystarczające do ponownego utworzenia śledzenia stosu.

Po ustawieniu kontekstu rejestru nowy kontekst rejestru jest używany dla wszystkich poleceń korzystających z wartości rejestru, takich jak k (Display Stack Backtrace) i r (Rejestry).

Jednak podczas debugowania komputerów wieloprocesorowych niektóre polecenia umożliwiają określenie procesora. (Aby uzyskać więcej informacji na temat takich poleceń, zobacz Składnia wieloprocesorowa). Jeśli określisz procesor dla polecenia, polecenie używa kontekstu rejestru aktywnego wątku w określonym procesorze zamiast bieżącego kontekstu rejestru, nawet jeśli określony procesor jest aktualnie aktywnym procesorem.

Ponadto jeśli kontekst rejestru nie jest zgodny z bieżącym ustawieniem trybu procesora, te polecenia generują niepoprawne lub bezsensowne dane wyjściowe. Aby uniknąć błędów wyjściowych, polecenia zależne od stanu rejestracji kończą się niepowodzeniem, dopóki nie zmienisz trybu procesora tak, aby był zgodny z kontekstem rejestru. Aby zmienić tryb procesora, użyj polecenia .effmach (Effective Machine),

Zmiana kontekstu rejestru może również zmienić kontekst lokalny. W ten sposób kontekst rejestru może mieć wpływ na wyświetlanie zmiennych lokalnych.

Jeśli wystąpi jakiekolwiek wykonywanie aplikacji, wykonywanie kroków lub śledzenie, kontekst rejestru jest natychmiast resetowany w celu dopasowania do pozycji licznika programu. W trybie użytkownika kontekst rejestru jest również resetowany, jeśli bieżący proces lub wątek zostanie zmieniony.

Kontekst rejestru ma wpływ na ślady stosu, ponieważ ślad stosu rozpoczyna się w lokalizacji, do której wskazuje rejestr wskaźnika stosu (esp na procesorze opartym na architekturze x86). Jeśli kontekst rejestru jest ustawiony na nieprawidłową lub niedostępną wartość, nie można uzyskać śladów stosu.

Punkt przerwania procesora (punkt przerwania danych) można zastosować do określonego kontekstu rejestru, używając polecenia .apply_dbp (Zastosuj punkt przerwania danych do kontekstu).

Kontekst lokalny

Podczas wykonywania programu znaczenie zmiennych lokalnych zależy od lokalizacji licznika programu, ponieważ zakres takich zmiennych rozciąga się tylko na funkcję, w której są zdefiniowane.

Podczas debugowania w trybie użytkownika lub w trybie jądra debuger używa zakresu bieżącej funkcji (bieżącej ramki na stosie) jako kontekstu lokalnego. Aby zmienić ten kontekst, użyj polecenia .frame (Ustaw kontekst lokalny) lub kliknij dwukrotnie żądaną ramkę w oknie Wywołania.

W przypadku debugowania w trybie użytkownika lokalny kontekst jest zawsze częścią śledzenia stosu bieżącego wątku. Podczas debugowania w trybie jądra lokalny kontekst jest zawsze kolejną ramką w śladzie stosu wątku aktualnego kontekstu rejestrów.

Dla kontekstu lokalnego można używać tylko jednej ramki stosowej. Nie można uzyskać dostępu do zmiennych lokalnych w innych ramkach.

Kontekst lokalny jest resetowany, jeśli wystąpi dowolne z następujących zdarzeń:

  • Dowolne wykonywanie programu, wykonywanie kroków lub śledzenie

  • Dowolne użycie ogranicznika wątku (~) w dowolnym poleceniu

  • Każda zmiana kontekstu rejestracji

Rozszerzenie !for_each_frame umożliwia wielokrotne wykonywanie pojedynczego polecenia, raz dla każdej ramki w stosie. To polecenie zmienia kontekst lokalny dla każdej ramki, wykonuje określone polecenie, a następnie zwraca kontekst lokalny do oryginalnej wartości.