Freigeben über


ICorProfilerInfo2::DoStackSnapshot-Methode

Aktualisiert: November 2007

Durchläuft die verwalteten Frames auf dem Stapel für den angegebenen Thread und sendet über einen Rückruf Informationen an den Profiler.

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);

Parameter

  • thread
    [in] Die ID des Zielthreads.

    Bei Übergabe von NULL in thread ergibt sich ein Snapshot des aktuellen Threads. Wenn eine ThreadID eines anderen Threads übergeben wird, hält die Common Language Runtime (CLR) diesen Thread an, erstellt einen Snapshot und setzt dann den Thread fort.

  • callback
    [in] Ein Zeiger auf die Implementierung der StackSnapshotCallback-Methode, die von der CLR aufgerufen wird, um dem Profiler Informationen zu jedem verwalteten Frame und jeder Ausführung von nicht verwalteten Frames bereitzustellen.

    Die StackSnapshotCallback-Methode wird vom Profilerwriter implementiert.

  • infoFlags
    [in] Ein Wert der COR_PRF_SNAPSHOT_INFO-Enumeration, der die Datenmenge angibt, die StackSnapshotCallback für jeden Frame zurückgeben soll.

  • clientData
    [in] Ein Zeiger auf die Clientdaten, die direkt an die StackSnapshotCallback-Rückruffunktion zurückgegeben werden.

  • context
    [in] Ein Zeiger auf eine Win32-CONTEXT-Struktur, die verwendet wird, um den Stackwalk zu starten. Die Win32-CONTEXT-Struktur enthält Werte der CPU-Register und stellt den Zustand der CPU zu einem bestimmten Zeitpunkt dar.

    Mithilfe des Startwerts bestimmt die CLR, wo der Stackwalk beginnt, sofern sich ganz oben im Stapel nicht verwalteter Hilfscode befindet. Andernfalls wird der Startwert ignoriert. Für einen asynchronen Durchlauf muss ein Startwert angegeben werden. Wenn Sie einen synchronen Durchlauf durchführen, ist kein Startwert erforderlich.

    Der context-Parameter ist nur gültig, wenn das COR_PRF_SNAPSHOT_CONTEXT-Flag im infoFlags-Parameter übergeben wurde.

  • contextSize
    [in] Die Größe der CONTEXT-Struktur, auf die vom context-Parameter verwiesen wird.

Hinweise

Bei Übergabe von NULL für thread ergibt sich ein Snapshot des aktuellen Threads. Snapshots können aus anderen Threads nur dann erstellt werden, wenn der Zielthread in diesem Moment angehalten ist.

Wenn der Profiler den Stapel durchlaufen möchte, ruft er DoStackSnapshot auf. Bevor die CLR von diesem Aufruf zurückgegeben wird, ruft sie StackSnapshotCallback mehrere Male auf, einmal für jeden verwalteten Frame (oder die Ausführung von nicht verwalteten Frames) im Stapel. Für nicht verwaltete Frames müssen Sie den Durchlauf selbst durchführen.

Die Reihenfolge, in der der Stapel durchlaufen wird, ist entgegengesetzt zur Reihenfolge, in der die Frames auf den Stapel verschoben wurden: Endframe (zuletzt verschoben) zuerst, Hauptframe (zuerst verschoben) zuletzt.

Weitere Informationen darüber, wie Sie den Profiler zum Durchlaufen verwalteter Stapel programmieren, finden Sie in der MSDN Library unter Profiler Stack Walking in the .NET Framework 2.0: Basics and Beyond.

Ein Stackwalk kann synchron oder asynchron sein, wie in den folgenden Abschnitten erklärt.

Synchroner Stackwalk

Ein synchroner Stackwalk umfasst das Durchlaufen des Stapels des aktuellen Threads als Reaktion auf einen Rückruf. Ein Startwert oder Anhalten ist nicht erforderlich.

Sie führen einen synchronen Aufruf durch, wenn die CLR eine der ICorProfilerCallback-Methoden (oder ICorProfilerCallback2-Methoden) des Profilers aufruft und Sie als Reaktion darauf einen DoStackSnapshot aufrufen, um den Stapel des aktuellen Threads zu durchlaufen. Dies ist hilfreich, wenn Sie wissen möchten, wie der Stapel bei einer Benachrichtigung wie ICorProfilerCallback::ObjectAllocated aussieht. Sie rufen einfach DoStackSnapshot in der ICorProfilerCallback-Methode auf und übergeben NULL im context-Parameter und im thread-Parameter.

Asynchroner Stackwalk

Ein asynchroner Stackwalk sieht das Durchlaufen des Stapels eines anderen Threads vor oder das Durchlaufen des aktuellen Threads. Dies geschieht nicht als Reaktion auf einen Rückruf, sondern durch Fremdsteuerung des Anweisungszeigers des aktuellen Threads. Für den asynchronen Durchlauf ist ein Startwert erforderlich, sofern sich ganz oben im Stapel nicht verwalteter Hilfscode befindet, der nicht Teil des Plattformaufrufs (PInvoke) oder COM-Aufrufs ist, sondern Hilfscode in der CLR darstellt. Es handelt sich beispielsweise bei Code, der Just-In-Time-Kompilierung (JIT) oder Garbage Collection ausführt, um Hilfscode.

Einen Startwert erhalten Sie, indem Sie den Zielthread direkt anhalten und den Stapel selbst durchlaufen, bis Sie den obersten verwalteten Frame erreichen. Nachdem der Zielthread angehalten wurde, rufen Sie den aktuellen Registerkontext des Zielthreads ab. Als Nächstes ermitteln Sie, ob der Registerkontext auf nicht verwalteten Code zeigt. Hierzu rufen Sie ICorProfilerInfo::GetFunctionFromIP auf. Wenn eine FunctionID mit dem Wert 0 (null) zurückgegeben wird, handelt es sich bei dem Frame um nicht verwalteten Code. Durchlaufen Sie jetzt den Stapel, bis Sie den ersten verwalteten Frame erreichen. Berechnen Sie anschließend anhand des Registerkontexts für diesen Frame den Startwertkontext.

Rufen Sie DoStackSnapshot mit dem Startwertkontext auf, um den asynchronen Stackwalk zu starten. Wenn Sie keinen Startwert angeben, überspringt DoStackSnapshot möglicherweise die verwalteten Frames oben im Stapel, und ein unvollständiger Stackwalk ist die Folge. Wenn Sie einen Startwert angeben, muss er auf JIT-kompilierten oder auf mit Native Image Generator (Ngen.exe) generierten Code zeigen. Andernfalls gibt DoStackSnapshot den Fehlercode CORPROF_E_STACKSNAPSHOT_UNMANAGED_CTX zurück.

Asynchrone Stackwalks können leicht Deadlocks oder Zugriffsverletzungen verursachen. Folgen Sie deshalb diesen Richtlinien:

  • Wenn Sie einen Thread direkt anhalten, sollten Sie beachten, dass nur ein Thread, der noch nie verwalteten Code ausgeführt hat, einen anderen Thread anhalten kann.

  • Blockieren Sie den ICorProfilerCallback::ThreadDestroyed-Rückruf immer, bis der Stackwalk dieses Threads abgeschlossen ist.

  • Es darf keine Sperre vorliegen, solange der Profiler eine CLR-Funktion aufruft, die eine Garbage Collection auslösen kann. Das heißt, es darf keine Sperre vorliegen, solange der besitzende Thread einen Aufruf durchführen kann, der eine Garbage Collection auslöst.

Anforderungen

Plattformen: siehe Systemanforderungen für .NET Framework.

Header: CorProf.h

Bibliothek: CorProf.idl

.NET Framework-Versionen: 3.5 SP1, 3.5, 3.0 SP1, 3.0, 2.0 SP1, 2.0

Siehe auch

Referenz

ICorProfilerInfo

ICorProfilerInfo2