Udostępnij za pośrednictwem


ICorProfilerInfo2::DoStackSnapshot — Metoda

Przechodzi przez zarządzane ramki na stosie dla określonego wątku i wysyła informacje do profilera za pośrednictwem wywołania zwrotnego.

Składnia

HRESULT DoStackSnapshot(  
    [in] ThreadID thread,  
    [in] StackSnapshotCallback *callback,  
    [in] ULONG32 infoFlags,  
    [in] void *clientData,  
    [in, size_is(contextSize), length_is(contextSize)] BYTE context[],  
    [in] ULONG32 contextSize);  

Parametry

thread
[in] Identyfikator wątku docelowego.

Przekazywanie wartości null w elemencie thread daje migawkę bieżącego wątku. W przypadku przekazania innego ThreadID wątku środowisko uruchomieniowe języka wspólnego (CLR) zawiesza ten wątek, wykonuje migawkę i wznawia działanie.

callback
[in] Wskaźnik do implementacji metody StackSnapshotCallback , która jest wywoływana przez CLR w celu udostępnienia profilera informacji na temat każdej zarządzanej ramki i każdego uruchomienia ramek niezarządzanych.

Metoda StackSnapshotCallback jest implementowana przez moduł zapisywania profilera.

infoFlags
[in] Wartość wyliczenia COR_PRF_SNAPSHOT_INFO , która określa ilość danych, które mają być przekazywane z powrotem dla każdej ramki przez StackSnapshotCallback.

clientData
[in] Wskaźnik do danych klienta, który jest przekazywany bezpośrednio do funkcji wywołania zwrotnego StackSnapshotCallback .

context
[in] Wskaźnik do struktury Win32 CONTEXT , która jest używana do inicjowania stosu walk. Struktura Win32 CONTEXT zawiera wartości rejestrów procesora CPU i reprezentuje stan procesora CPU w określonym momencie w czasie.

Inicjator pomaga CLR określić miejsce rozpoczęcia stosu, jeśli górny stos jest niezarządzany kod pomocnika; w przeciwnym razie inicjator jest ignorowany. Nasion należy dostarczyć do asynchronicznego spaceru. Jeśli robisz synchroniczny spacer, nie jest konieczne żadne nasion.

Parametr jest prawidłowy tylko wtedy, gdy flaga context COR_PRF_SNAPSHOT_CONTEXT została przekazana w parametrze infoFlags .

contextSize
[in] Rozmiar CONTEXT struktury, do której context odwołuje się parametr .

Uwagi

Przekazywanie wartości null dla thread daje migawkę bieżącego wątku. Migawki mogą być wykonywane z innych wątków tylko wtedy, gdy wątek docelowy jest zawieszony w tym czasie.

Gdy profiler chce przejść przez stos, wywołuje metodę DoStackSnapshot. Zanim clR powróci z tego wywołania, wywołuje kilka StackSnapshotCallback razy raz dla każdej zarządzanej ramki (lub uruchomienia niezarządzanych ramek) na stosie. Gdy napotkane są niezarządzane ramki, musisz je samodzielnie przejść.

Kolejność stosu jest odwrotna od tego, jak ramki zostały wypchnięte na stos: liść (ostatni wypchnięty) ramka pierwsza, główna (pierwsza wypchnięta) ramka ostatnia.

Aby uzyskać więcej informacji na temat programowania profilera w celu chodzenia zarządzanych stosów, zobacz Profiler Stack Walking in the .NET Framework 2.0: Basics and Beyond (Profiler Stack Walking w .NET Framework 2.0: Podstawy i poza nią).

Przewodnik stosu może być synchroniczny lub asynchroniczny, jak wyjaśniono w poniższych sekcjach.

Synchroniczny przewodnik stosu

Synchroniczny przewodnik stosu polega na przejściu stosu bieżącego wątku w odpowiedzi na wywołanie zwrotne. Nie wymaga rozmieszczania ani zawieszania.

Wykonasz wywołanie synchroniczne, gdy w odpowiedzi na wywołanie środowiska CLR jednego z metod ICorProfilerCallback (lub ICorProfilerCallback2) profilera profilera wywołujesz DoStackSnapshot metodę , aby przejść przez stos bieżącego wątku. Jest to przydatne, gdy chcesz zobaczyć, jak wygląda stos w powiadomieniu, takim jak ICorProfilerCallback::ObjectAllocated. Wystarczy wywołać metodę DoStackSnapshot z poziomu ICorProfilerCallback metody , przekazując wartość null w parametrach context i thread .

Asynchroniczny przewodnik stosu

Asynchroniczny spacer stosu pociąga za sobą chodzenie stosu innego wątku lub chodzenie stosu bieżącego wątku, nie w odpowiedzi na wywołanie zwrotne, ale przez przejęcie wskaźnika instrukcji bieżącego wątku. Asynchroniczny przewodnik wymaga inicjującego, jeśli górna część stosu jest kodem niezarządzanym, który nie jest częścią wywołania platformy (PInvoke) lub wywołania MODELU COM, ale kod pomocnika w samym środowisku CLR. Na przykład kod, który kompiluje just-in-time (JIT) lub wyrzucanie elementów bezużytecznych, jest kodem pomocnika.

Nasion można uzyskać bezpośrednio zawieszając wątek docelowy i chodzenie stosu samodzielnie, aż znajdziesz najbardziej zarządzaną ramkę. Po wstrzymaniu wątku docelowego pobierz bieżący kontekst rejestru wątku docelowego. Następnie określ, czy kontekst rejestru wskazuje niezarządzany kod, wywołując metodę ICorProfilerInfo::GetFunctionFromIP — jeśli zwraca wartość równą FunctionID zero, ramka jest niezarządzanym kodem. Teraz przejmij stos do momentu osiągnięcia pierwszej zarządzanej ramki, a następnie oblicz kontekst inicjujący na podstawie kontekstu rejestru dla tej ramki.

Wywołaj DoStackSnapshot metodę z kontekstem inicjowania, aby rozpocząć asynchroniczny przewodnik stosu. Jeśli nie podasz inicjuj, DoStackSnapshot może pominąć zarządzane ramki u góry stosu, a w związku z tym da ci niekompletny spacer stosu. Jeśli podasz inicjator, musi wskazywać kod generowany przez JIT lub Generator obrazów natywnych (Ngen.exe); DoStackSnapshot w przeciwnym razie zwraca kod błędu CORPROF_E_STACKSNAPSHOT_UNMANAGED_CTX.

Asynchroniczne spacery stosu mogą łatwo powodować zakleszczenia lub naruszenia dostępu, chyba że przestrzegasz następujących wytycznych:

  • Podczas bezpośredniego zawieszania wątków należy pamiętać, że tylko wątek, który nigdy nie uruchamia kodu zarządzanego, może zawiesić inny wątek.

  • Zawsze blokuj w wywołaniu zwrotnym ICorProfilerCallback::ThreadDestroyed , dopóki ten wątek nie zostanie ukończony.

  • Nie należy przechowywać blokady, gdy profiler wywołuje funkcję CLR, która może wyzwolić odzyskiwanie pamięci. Oznacza to, że nie należy przechowywać blokady, jeśli wątek będącego właścicielem może wywołać wyzwalające odzyskiwanie pamięci.

Istnieje również ryzyko zakleszczenia w przypadku wywołania DoStackSnapshot z wątku utworzonego przez profilera, aby można było przejść stos oddzielnego wątku docelowego. Przy pierwszym wejściu utworzonego wątku do pewnych ICorProfilerInfo* metod (w tym DoStackSnapshot) clR wykona inicjację specyficzną dla poszczególnych wątków clR w tym wątku. Jeśli profiler zawiesił wątek docelowy, którego stos próbujesz chodzić, a jeśli ten wątek docelowy miał być właścicielem blokady niezbędnej do wykonania inicjalizacji poszczególnych wątków, nastąpi zakleszczenie. Aby uniknąć tego zakleszczenia, wykonaj początkowe wywołanie DoStackSnapshot z wątku utworzonego przez profilera, aby przejść oddzielny wątek docelowy, ale nie należy najpierw zawiesić wątku docelowego. To początkowe wywołanie gwarantuje, że inicjowanie poszczególnych wątków może zakończyć się bez zakleszczenia. Jeśli DoStackSnapshot zakończy się powodzeniem i zgłosi co najmniej jedną ramkę, po tym momencie będzie to bezpieczne dla tego wątku utworzonego przez profilera, aby zawiesić dowolny wątek docelowy i wywołać DoStackSnapshot go, aby przejść stos tego wątku docelowego.

Wymagania

Platformy: Zobacz Wymagania systemowe.

Nagłówka: CorProf.idl, CorProf.h

Biblioteki: CorGuids.lib

wersje .NET Framework: dostępne od wersji 2.0

Zobacz też