Método de ICorProfilerInfo2::DoStackSnapshot
Percorre os quadros gerenciados na pilha para o segmento especificado e envia informações para o criador de perfil por meio de um retorno de chamada.
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);
Parâmetros
thread
[in] A ID do thread-alvo.Passar nulo no thread gera um instantâneo do thread atual. Se um ThreadID de um thread diferente é passado, o common language runtime (CLR) suspende o thread, executa o instantâneo e currículos.
callback
[in] Um ponteiro para a implementação de StackSnapshotCallback método, que é chamado pelo CLR para fornecer o profiler com informações em cada quadro gerenciado e cada execução de quadros não gerenciados.O StackSnapshotCallback método é implementado pelo gravador profiler.
infoFlags
[in] Um valor igual a COR_PRF_SNAPSHOT_INFO enumeração, que especifica a quantidade de dados a serem passados de volta para cada quadro por StackSnapshotCallback.clientData
[in] Um ponteiro para os dados do cliente, o que são passados diretamente para o StackSnapshotCallback função de retorno de chamada.context
[in] Um ponteiro para um Win32 CONTEXT estrutura, que é usada para propagar a movimentação de pilha. O Win32 CONTEXT estrutura contém valores de registradores de CPU e representa o estado da CPU em um momento específico no tempo.A semente, que ajuda o CLR determinar onde começar a movimentação de pilha, se o topo da pilha for código não gerenciado auxiliar; Caso contrário, a semente é ignorada. Uma semente deve ser fornecida para uma movimentação assíncrona. Se você estiver fazendo uma movimentação assíncrona, sem semente é necessário.
O context parâmetro é válido somente se o sinalizador COR_PRF_SNAPSHOT_CONTEXT foi passado a infoFlags parâmetro.
contextSize
[in] O tamanho da CONTEXT estrutura, que é referenciada pela context parâmetro.
Comentários
Passar null para thread gera um instantâneo do thread atual. Instantâneos podem ser criados de outros segmentos somente se o thread-alvo está suspensa no momento.
Quando o gerador de perfil deseja movimentar a pilha, ele chama DoStackSnapshot. Antes do CLR retorna daquela chamada, ele chama o StackSnapshotCallback várias vezes, uma vez para cada um gerenciado quadro (ou execução de quadros não gerenciados) na pilha. Quando os quadros não gerenciados são encontrados, você deve movimentá-los por conta própria.
A ordem na qual a pilha é movimentada é o inverso de como os quadros foram colocados na pilha: folha (último colocado) quadro primeiro e principal quadro (colocado primeiro) pela última vez.
Para obter mais informações sobre como programar o gerador de perfil para movimentar pilhas gerenciadas, consulte o Profiler empilhar caminhar sobre o.NET Framework 2.0: Noções básicas e Beyond em que o Biblioteca MSDN.
A movimentação de pilha pode ser síncrono ou assíncrono, conforme explicado nas seções a seguir.
Movimentação de pilha assíncrona
Uma movimentação de pilha síncronas envolve a movimentação de pilha do thread atual em resposta a um retorno de chamada. Não exige a propagação ou suspensão.
Fazer um síncrono chamar e quando, em resposta ao CLR chamando um dos seu gerador de perfil ICorProfilerCallback (ou ICorProfilerCallback2) métodos, chame DoStackSnapshot para movimentar a pilha do thread atual. Isso é útil quando você deseja ver a pilha de aparência em uma notificação, como ICorProfilerCallback::ObjectAllocated. Você acabou de chamar DoStackSnapshot a partir do seu ICorProfilerCallback método, passar null na context e thread parâmetros.
Movimentação de pilha assíncrona
Uma movimentação de pilha assíncrona implica a movimentar a pilha de um thread diferente ou movimentar a pilha do segmento atual, não em resposta a um retorno de chamada, mas pelo ponteiro de instrução atual do segmento de seqüestro. Uma movimentação assíncrona requer uma semente, se o topo da pilha for código não gerenciado que não faz parte de uma plataforma invoke (PInvoke) ou a chamada COM, mas o código auxiliar no próprio CLR. Por exemplo, o código que faz o just-in-time (JIT) compilação ou coleta de lixo é o código auxiliar.
Você obtém uma semente suspendendo diretamente o thread-alvo e movimentar a pilha sozinho, até encontrar o primeiro quadro gerenciado. Depois que o thread-alvo é suspenso, obtenha o contexto de registro atual do thread-alvo. Em seguida, determine se o contexto de registro aponta para o código não gerenciado chamando ICorProfilerInfo::GetFunctionFromIP — se ela retorna um FunctionID igual a zero, o quadro é código não gerenciado. Agora, movimentar a pilha até que chegar primeiro quadro gerenciado e, em seguida, calcular o contexto de propagação, com base no contexto de registro que o quadro.
Chame DoStackSnapshot com o contexto de sua semente para começar a movimentação de pilha assíncrona. Se você não fornecer uma semente, DoStackSnapshot pode ignorar quadros gerenciados na parte superior da pilha e, conseqüentemente, lhe dará uma movimentação de pilha incompleta. Se você fornecer uma semente, ele deve apontar para a compilação JIT ou Native Image Generator (NGen. exe)-gerado código; Caso contrário, DoStackSnapshot retorna o código de falha CORPROF_E_STACKSNAPSHOT_UNMANAGED_CTX.
Movimentações de pilha assíncrona podem facilmente causar deadlocks ou violações, de acesso, a menos que você siga estas diretrizes:
Quando você diretamente suspende os threads, lembre-se de que somente um thread nunca executou código gerenciado pode suspender outro thread.
Sempre bloquear sua ICorProfilerCallback::ThreadDestroyed o retorno de chamada até a conclusão da movimentação de pilha do segmento.
Não segure um bloqueio enquanto seu gerador de perfil chama uma função CLR que podem disparar uma coleta de lixo. Ou seja, não segure um bloqueio se o thread que pode fazer uma chamada que dispara uma coleta de lixo.
Há também um risco de deadlock se você chamar DoStackSnapshot de um segmento que seu gerador de perfil foi criado para que você pode movimentar a pilha de um thread de destino separado. Na primeira vez que o thread que você criou insere determinados ICorProfilerInfo* métodos (incluindo DoStackSnapshot), o CLR realizará por thread, inicialização de CLR específica no thread. Se o seu gerador de perfil suspendeu cuja pilha que você está tentando movimentar o thread-alvo e se esse thread de destino possuir um bloqueio necessárias para executar essa inicialização por segmento, ocorrerá um deadlock. Para evitar esse deadlock, fazer uma chamada inicial em DoStackSnapshot de seu segmento criado o profiler para movimentar um separado thread de destino, mas não suspender o thread-alvo primeiro. Essa chamada inicial garante que a inicialização por thread pode concluir sem deadlock. Se DoStackSnapshot tiver êxito e relata pelo menos um quadro, após esse ponto será seguro para thread criado o profiler suspender qualquer thread-alvo e a chamada DoStackSnapshot para movimentar a pilha do thread que destino.
Requisitos
Plataformas: Consulte Requisitos de sistema do .NET Framework.
Cabeçalho: Corprof. idl, CorProf.h
Biblioteca: CorGuids.lib
.NET Framework versões: 4, 3.5 SP1, 3.5, 3.0 SP1, 3.0, 2.0 SP1, 2.0