Sdílet prostřednictvím


ICorProfilerInfo2::DoStackSnapshot – metoda

Provede spravované rámce v zásobníku pro zadané vlákno a odešle informace profileru prostřednictvím zpětného volání.

Syntaxe

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
[v] ID cílového vlákna.

Předání hodnoty null v thread vytvoří snímek aktuálního vlákna. Pokud se předá a ThreadID z jiného vlákna, modul CLR (Common Language Runtime) toto vlákno pozastaví, provede snímek a obnoví se.

callback
[v] Ukazatel na implementaci StackSnapshotCallback metoda, která je volána CLR poskytnout profileru informace o každém spravovaném rámci a každém spuštění nespravovaných rámců.

Metodu StackSnapshotCallback implementuje zapisovač profileru.

infoFlags
[v] Hodnota COR_PRF_SNAPSHOT_INFO výčtu , která určuje množství dat, která mají být předána zpět pro každý snímek pomocí StackSnapshotCallback.

clientData
[v] Ukazatel na data klienta, který se předává přímo do funkce zpětného StackSnapshotCallback volání.

context
[v] Ukazatel na strukturu Win32 CONTEXT , která se používá k vytvoření zásobníku chůze. Struktura Win32 CONTEXT obsahuje hodnoty registrů procesoru a představuje stav procesoru v určitém okamžiku v čase.

Počáteční hodnota pomáhá CLR určit, kde začít trasu zásobníku, pokud je horní část zásobníku nespravovaný pomocný kód; jinak bude počáteční hodnota ignorována. Pro asynchronní procházení musí být zadána počáteční hodnota. Pokud provádíte synchronní procházku, není potřeba žádná počáteční hodnota.

Parametr context je platný pouze v případě, že byl v parametru infoFlags předán příznak COR_PRF_SNAPSHOT_CONTEXT.

contextSize
[v] Velikost CONTEXT struktury, na kterou odkazuje context parametr .

Poznámky

Předání hodnoty null pro thread vytvoří snímek aktuálního vlákna. Snímky jiných vláken lze pořídit pouze v případě, že je cílové vlákno v době pozastavení.

Když chce profiler procházet zásobníkem, volá DoStackSnapshot. Než se CLR vrátí z tohoto volání, zavolá váš StackSnapshotCallback několikrát, jednou pro každý spravovaný rámec (nebo spuštění nespravovaných rámců) v zásobníku. Když se setkáte s nespravovanými rámečky, musíte je projít sami.

Pořadí, ve kterém je zásobník procházený, je opačné od toho, jak byly rámce zasunuty do štosu: listový (poslední) snímek první, hlavní (první posunuté) snímek poslední.

Další informace o tom, jak naprogramovat profiler tak, aby procházel spravované zásobníky, naleznete v tématu Profiler Stack Walking v rozhraní .NET Framework 2.0: Základy a další.

Postup zásobníku může být synchronní nebo asynchronní, jak je vysvětleno v následujících částech.

Synchronní procházka zásobníkem

Synchronní procházení zásobníku zahrnuje procházení zásobníku aktuálního vlákna v reakci na zpětné volání. Nevyžaduje se seeding ani pozastavení.

Provedete synchronní volání, když v reakci na volání CLR jeden z profiler ICorProfilerCallback (nebo ICorProfilerCallback2) metody, volání DoStackSnapshot procházet zásobník aktuální vlákno. To je užitečné, když chcete vidět, jak zásobník vypadá v oznámení, například ICorProfilerCallback::ObjectAllocated. Stačí volat DoStackSnapshot z vaší ICorProfilerCallback metody a předat null v parametrech context a thread .

Asynchronní procházka zásobníkem

Asynchronní procházení zásobníku zahrnuje procházení zásobníku jiného vlákna nebo procházení zásobníku aktuálního vlákna, nikoli v reakci na zpětné volání, ale napadení ukazatele instrukce aktuálního vlákna. Asynchronní procházka vyžaduje předsadu, pokud je horní část zásobníku nespravovaný kód, který není součástí volání platformy (PInvoke) nebo volání modelu COM, ale pomocný kód v samotném MODULUR. Například kód, který provádí kompilaci za běhu (JIT) nebo uvolňování paměti, je pomocným kódem.

Počáteční hodnotu získáte přímým pozastavením cílového vlákna a procházením jeho zásobníku sami, dokud nenajdete nejvyšší spravovaný rámec. Po pozastavení cílového vlákna získejte aktuální kontext registru cílového vlákna. Dále určete, zda registr kontext odkazuje na nespravovaný kód voláním ICorProfilerInfo::GetFunctionFromIP – pokud vrátí rovnu FunctionID nule, rámec je nespravovaný kód. Teď projděte zásobníkem, dokud se nedostanete k prvnímu spravovanému rámci, a pak vypočítejte počáteční kontext na základě kontextu registru pro tento rámec.

Voláním DoStackSnapshot s počátečním kontextem zahájíte asynchronní trasu zásobníku. Pokud nezadáte počáteční hodnotu, DoStackSnapshot může přeskočit spravované rámce v horní části zásobníku a v důsledku toho vám poskytne neúplný postup zásobníku. Pokud zadáte seed, musí odkazovat na jit-kompilovaný nebo Native Image Generator (Ngen.exe)-vygenerovaný kód; DoStackSnapshot v opačném případě vrátí kód chyby CORPROF_E_STACKSNAPSHOT_UNMANAGED_CTX.

Asynchronní procházky zásobníkem můžou snadno způsobit zablokování nebo narušení přístupu, pokud nedodržíte tyto pokyny:

  • Když přímo pozastavíte vlákna, mějte na paměti, že pouze vlákno, které nikdy nespustí spravovaný kód, může pozastavit jiné vlákno.

  • Vždy blokovat v ICorProfilerCallback::ThreadDestroyed zpětné volání, dokud nebude dokončeno zásobníku vlákna.

  • Během volání profileru do funkce CLR, která může aktivovat uvolňování paměti, nedržte zámek. To znamená, že nedržte zámek, pokud vlastnící vlákno může provést volání, které aktivuje uvolňování paměti.

Existuje také riziko vzájemného zablokování, pokud voláte DoStackSnapshot z vlákna vytvořeného profilerem, abyste mohli procházet zásobník samostatného cílového vlákna. Když vlákno, které jste vytvořili poprvé, zadá určité ICorProfilerInfo* metody (včetně DoStackSnapshot), clr provede inicializaci pro každé vlákno specifické pro CLR v daném vlákně. Pokud váš profiler pozastavil cílové vlákno, jehož zásobník se pokoušíte procházet, a pokud se stalo, že cílové vlákno vlastní zámek nezbytný pro provedení této inicializace jednotlivých vláken, dojde k zablokování. Chcete-li se tomuto zablokování vyhnout, proveďte počáteční volání DoStackSnapshot z vlákna vytvořeného profilerem, abyste prošli samostatné cílové vlákno, ale nejprve cílové vlákno nepozastavujte. Toto počáteční volání zajišťuje, že se inicializace jednotlivých vláken může dokončit bez vzájemného zablokování. Pokud DoStackSnapshot proběhne úspěšně a nahlásí alespoň jeden snímek, bude po tomto okamžiku bezpečné, aby vlákno vytvořené profilerem pozastavit jakékoli cílové vlákno a volat DoStackSnapshot k procházení zásobníku tohoto cílového vlákna.

Požadavky

Platformy: Viz Požadavky na systém.

Záhlaví: CorProf.idl, CorProf.h

Knihovny: CorGuids.lib

Verze rozhraní .NET Framework: K dispozici od verze 2.0

Viz také