DTrace no Windows
O DTrace (DTrace.exe) é uma ferramenta de linha de comando que exibe informações e eventos do sistema. O DTrace é uma plataforma de rastreamento de código aberto portada para janelas. O DTrace foi originalmente desenvolvido para o sistema operacional Solaris. Ele fornece instrumentação dinâmica de ambas as funções do usuário/kernel, a capacidade de script usando a linguagem D, rastreamento especulativo. Além disso, o DTrace tem extensões específicas do sistema operacional Windows, como instrumentação ETW, geração de eventos ETW, testes de chamada do sistema e recursos de captura de despejo ao vivo.
Observação
O DTrace tem suporte nos builds do Insider do Windows após a versão 18980 e a compilação 18975 do Windows Server.
O site do DTrace no GitHub do Windows está localizado aqui:
https://github.com/microsoft/DTrace-on-Windows
Abrir informações do DTrace
Para obter informações detalhadas sobre o DTrace, confira a Especificação OpenDTrace versão 1.0 na Universidade de Cambridge.
O site principal do GitHub está localizado em https://github.com/opendtrace/.
Um conjunto de scripts úteis está disponível em https://github.com/opendtrace/toolkit.
Vários livros do DTrace estão disponíveis, tais como:
DTrace: Dynamic Tracing in Oracle Solaris, Mac OS X and FreeBSD por Brendan Gregg e Jim Mauro
Solaris Performance and Tools: DTrace and MDB Techniques for Solaris 10 and OpenSolaris por Richard McDougall, Jim Mauro e Brendan Gregg
Fornecer comentários sobre o Windows DTrace
Use o hub de comentários para solicitar novos recursos ou relatar problemas ou bugs com o Windows DTrace.
- Para iniciar o hub de comentários no Windows, vá para pesquisar, insira a palavra comentários e selecione Hub de Feedback.
- Selecione Sugerir um recurso ou Relatar um problema.
- Forneça uma descrição detalhada e específica do problema ou sugestão.
Extensões do Windows do DTrace
A seguir estão alguns dos provedores Dtrace disponíveis no Windows e o que eles instrumentam.
syscall – chamadas do sistema NTOS
fbt (Function Boundary Tracing) – entrada e retornos da função Kernel
pid (ID do processo) – rastreamento de processo no modo de usuário. Como o modo kernel FBT, mas também permitindo a instrumentação de deslocamentos de funções arbitrárias.
etw (Event Tracing for Windows) – permite a definição de testes para ETW. Esse provedor ajuda a aproveitar a instrumentação do sistema operacional existente no DTrace.
SYSCALL – Chamadas do sistema NTOS
O SYSCALL fornece um par de testes para cada chamada do sistema: um teste de entrada que é acionado antes da inserção da chamada do sistema e um teste de retorno que é acionado após a conclusão da chamada do sistema, mas antes da transferência do controle para o nível de usuário. Para todos os testes SYSCALL, o nome da função é definido como o nome da chamada do sistema instrumentado e o nome do módulo é o módulo em que a função existe. Os nomes das chamadas do sistema fornecidos pelo provedor SYSCALL podem ser encontrados digitando o comando dtrace.exe -l -P syscall
no prompt de comando. Note que o nome do teste é syscall em letras minúsculas. O comando dtrace -ln syscall:::
também listará todos os testes e parâmetros disponíveis no provedor syscall.
C:\> dtrace -ln syscall:::
ID PROVIDER MODULE FUNCTION NAME
6 syscall NtWaitHighEventPair entry
7 syscall NtWaitHighEventPair return
8 syscall NtRegisterThreadTerminatePort entry
9 syscall NtRegisterThreadTerminatePort return
...
Note que nem toda a saída de tela é exibida nesses exemplos. "..." é usado para representar a saída truncada.
Para percorrer a saída, aplique o comando more da seguinte forma:
dtrace -ln syscall:::|more
Adicione a opção v para exibir mais informações sobre os testes syscall disponíveis.
C:\> dtrace -lvn syscall:::
...
942 syscall NtSaveMergedKeys entry
Probe Description Attributes
Identifier Names: Private
Data Semantics: Private
Dependency Class: ISA
Argument Attributes
Identifier Names: Private
Data Semantics: Private
Dependency Class: ISA
Argument Types
args[0]: HANDLE
args[1]: HANDLE
args[2]: HANDLE
...
ETW
O DTrace inclui suporte para testes ETW existentes manifestos/com log de rastreamento. Você pode instrumentar, filtrar e analisar eventos ETW de forma síncrona no momento do disparo do evento. Além disso, é possível usar o DTrace para associar vários eventos/estados do sistema para fornecer uma transmissão de saída consolidada para ajudar a depurar situações de erro complexas.
O comando dtrace -ln etw:::
também listará todos os testes e parâmetros disponíveis no provedor syscall.
C:\> dtrace -ln etw:::
ID PROVIDER MODULE FUNCTION NAME
944 etw 048dc470-37c1-52a8-565a-54cb27be37ec 0xff_0xffffffffffffffff generic_event
945 etw aab97afe-deaf-5882-1e3b-d7210f059dc1 0xff_0xffffffffffffffff generic_event
946 etw b0f40491-9ea6-5fd5-ccb1-0ec63be8b674 0xff_0xffffffffffffffff generic_event
947 etw 4ee869fa-9954-4b90-9a62-308c74f99d32 0xff_0xffffffffffffffff generic_event
...
Para saber mais, confira ETW do DTrace.
Function Boundary Tracing (FBT)
O provedor FBT (Function Boundary Tracing) fornece testes associados à entrada e ao retorno da maioria das funções no kernel do Windows. A função é a unidade fundamental do texto do programa. Semelhante a outros provedores do DTrace, o FBT não tem efeito de teste quando não está explicitamente habilitado. Quando ativado, o FBT apenas induz um efeito de teste em funções investigadas. O FBT foi implementado em plataformas x86 e x64.
Para cada conjunto de instruções, há um pequeno número de funções que não chamam outras funções e são altamente otimizadas pelo compilador (as chamadas funções folha) que não podem ser instrumentadas pelo FBT. Testes para essas funções não estão presentes no DTrace.
O comando dtrace -ln fbt:nt::
listará todos os testes e parâmetros disponíveis para o módulo nt. Use o comando do depurador lm (List Loaded Modules) para listar todos os módulos disponíveis.
C:\>dtrace -ln "fbt:nt::"
ID PROVIDER MODULE FUNCTION NAME
3336 fbt nt PiDqActionDataFree entry
3337 fbt nt PiDqActionDataFree return
3338 fbt nt PiDqActionDataGetRequestedProperties entry
3339 fbt nt PiDqActionDataGetRequestedProperties return
3340 fbt nt _CmGetMatchingFilteredDeviceInterfaceList entry
...
Observação
Como há milhares de chamadas disponíveis no nt, não convém deixar o nome da função vazio ao executar um comando do DTrace que registra dados. A abordagem recomendada para evitar um possível impacto no desempenho é especificar pelo menos parte do nome da função, como fbt:nt:*Timer*:entry
.
PID
O provedor PID do DTrace permite rastrear a execução interna de processos de modo de usuário, como um navegador da Web ou um banco de dados. Também é possível anexar o DTrace no momento da inicialização do processo para depurar problemas de inicialização do processo. Como parte da definição PID, você especifica as funções definidas no processo e deslocamentos específicos (ou todos os deslocamentos usando curinga *) dentro da função. O provedor PID exige que o binário seja iniciado ou executado no momento da execução do script.
Este comando de exemplo exibe informações sobre uma chamada específica no PID associado a notepad.exe. Use o comando do depurador lm (List Loaded Modules) para listar todos os módulos disponíveis.
C:\Windows\system32>dtrace -ln "pid$target:ntdll:RtlAllocateHeap:entry" -c notepad.exe
ID PROVIDER MODULE FUNCTION NAME
5102 pid6100 ntdll RtlAllocateHeap entry
Observação
Ao rastrear funções escritas em C++, os nomes de função podem ser muito longos ou decorados para serem especificados como um teste com a forma completa. Uma solução comum é usar uma expressão que corresponda unicamente à função de destino. Por exemplo, use 'String??Copy' como uma parte 'probefunc' do nome do teste para corresponder a 'String::Copy()', ou '*GetPinnableReference' para corresponder a 'String::GetPinnableReference()'.
Arquitetura do Windows DTrace
Os usuários interagem com o DTrace usando o comando DTrace, que atua como um front-end para o mecanismo do DTrace. Os scripts D são compilados em um formato intermediário (DIF) no espaço do usuário e enviados ao componente kernel do DTrace para execução, às vezes chamado de DIF Virtual Machine. Isso é executado no driver dtrace.sys.
Traceext.sys (extensão de rastreamento) é um driver de extensão de kernel do Windows, que permite que o Windows exponha a funcionalidade da qual o DTrace depende para fornecer rastreamento. O kernel do Windows fornece textos explicativos durante o stackwalk ou acessos à memória que são implementados pela extensão de rastreamento.
Instalar o DTrace no Windows
Verifique se você está executando uma versão compatível do Windows. O download atual do DTrace tem suporte nos builds do Insider do Windows 20H1 após a versão 18980 e o build 18975 do Windows Server. Não é recomendável instalar esta versão do DTrace em versões mais antigas do Windows porque pode gerar instabilidade do sistema. (A versão arquivada do DTrace para 19H1 não está mais disponível e não tem mais suporte.)
Baixe o arquivo de instalação MSI (Baixar o DTrace no Windows) a partir do Centro de Download da Microsoft.
Selecione a Instalação completa.
Importante
Antes de usar o bcdedit para alterar informações de inicialização, talvez seja necessário suspender temporariamente recursos de segurança do Windows, como Patchguard, BitLocker e Inicialização Segura, no PC de teste. Reabilite esses recursos de segurança quando o teste terminar e gerencie adequadamente o PC de teste, quando os recursos de segurança estiverem desabilitados.
Atualize a variável de ambiente PATH para incluir C:\Arquivos de Programas\DTrace
set PATH=%PATH%;"C:\Program Files\DTrace"
- Habilite o DTrace na máquina usando o comando bcdedit.
bcdedit /set dtrace ON
Ao atualizar para um novo build do Windows Insider, você precisará redefinir a opção dtrace bcdedit.
Observação
Se você estiver usando o BitLocker, desative-o ao fazer alterações nos valores de inicialização. Se você não fizer isso, poderá ser solicitado a fornecer a chave de recuperação do BitLocker. Para se recuperar dessa situação, uma forma é inicializar no console de recuperação e restaurar o valor bcdedit, bcdedit /set {default} dtrace on
. Se uma atualização do sistema operacional tiver removido o valor e você o tiver adicionado, para recuperar o sistema operacional, use bcdedit para remover o valor, bcdedit /deletevalue {default} dtrace
. Desabilite o BitLocker e reative o dtrace, bcdedit /set dtrace ON
.
Configure o VSM (Modo Seguro Virtual) na máquina para habilitar o FBT (rastreamento de limite de função do kernel) definindo "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceGuard\EnableVirtualizationBasedSecurity" definido como 1 para habilitar o VSM e o Kernel Seguro.
Para fazer isso, use o comando REG Add desta forma:
REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceGuard\ /v EnableVirtualizationBasedSecurity /t REG_DWORD /d 1
Alguns comandos do DTrace usam símbolos do Windows. Para usar símbolos do Windows, crie um diretório de símbolos e defina o caminho dos símbolos:
mkdir c:\symbols
set _NT_SYMBOL_PATH=srv*C:\symbols*https://msdl.microsoft.com/download/symbols
Para saber mais sobre caminhos de símbolos, confira Caminho de símbolo para depuradores do Windows.
Usar o DTrace em uma máquina virtual
Se estiver executando o DTrace em uma VM, ative a Virtualização aninhada na máquina que dá suporte à VM, quando a VM for interrompida, usando o comando do PowerShell a seguir. Forneça o <VMName>
para a VM em que o DTrace está em execução. Abra janelas do PowerShell como administrador.
Set-VMProcessor -VMName <VMName> -ExposeVirtualizationExtensions $true
Reinicialize o PC com suporte à VM.
Validar a instalação do DTrace
Use a opção -l para listar os testes ativos. Se o DTrace estiver ativo, muitos testes deverão ser listados para eventos etw e system.
Abra um prompt de comando do Windows como administrador para inserir comandos do DTrace.
C:\> dtrace -l
...
179 syscall NtLockVirtualMemory return
180 syscall NtDeviceIoControlFile entry
181 syscall NtDeviceIoControlFile return
182 syscall NtCreateUserProcess entry
183 syscall NtCreateUserProcess return
184 syscall NtQuerySection entry
185 syscall NtQuerySection return
...
3161 etw 222962ab-6180-4b88-a825-346b75f2a24a 0xff_0xffffffffffffffff generic_event
3162 etw 3ac66736-cc59-4cff-8115-8df50e39816b 0xff_0xffffffffffffffff generic_event
3163 etw 42695762-ea50-497a-9068-5cbbb35e0b95 0xff_0xffffffffffffffff generic_event
3164 etw 3beef58a-6e0f-445d-b2a4-37ab737bd47e 0xff_0xffffffffffffffff generic_event
...
Se apenas esses três testes estiverem listados, haverá um problema no carregamento do driver DTrace.sys.
C:\> dtrace -l
ID PROVIDER MODULE FUNCTION NAME
1 dtrace BEGIN
2 dtrace END
3 dtrace ERROR
Introdução ao DTrace - comandos de uma linha
Comece executando esses comandos em um prompt de comando do administrador.
Este comando exibe um resumo syscall por programa por 5 segundos. O parâmetro tick-5sec especifica o período de tempo. O parâmetro exit(0); leva à saída do comando ao concluir para que volte ao prompt de comando. A saída é especificada por meio de [pid,execname] = count();
Isso exibe a ID do processo (PID), o nome do executável e uma contagem para os últimos 5 segundos.
C:\> dtrace -Fn "tick-5sec {exit(0);} syscall:::entry{ @num[pid,execname] = count();} "
dtrace: description 'tick-5sec ' matched 471 probes
CPU FUNCTION
0 | :tick-5sec
1792 svchost.exe 4
4684 explorer.exe 4
4916 dllhost.exe 4
6192 svchost.exe 4
6644 SecurityHealth 4
92 TrustedInstall 5
504 csrss.exe 5
696 svchost.exe 6
...
Este comando resume as chamadas de timer set/cancel por 3 segundos:
C:\> dtrace -Fn "tick-3sec {exit(0);} syscall::Nt*Timer*:entry { @[probefunc, execname, pid] = count();}"
dtrace: description 'tick-3sec ' matched 14 probes
CPU FUNCTION
0 | :tick-3sec
NtCreateTimer WmiPrvSE.exe 948 1
NtCreateTimer svchost.exe 564 1
NtCreateTimer svchost.exe 1276 1
NtSetTimer2 svchost.exe 1076 1
NtSetTimer2 svchost.exe 7080 1
NtSetTimerEx WmiPrvSE.exe 948 1
...
Comandos de uma linha que usam símbolos
Esses comandos aproveitam os símbolos do Windows e exigem a definição do caminho do símbolo conforme discutido na seção de instalação. Como citado anteriormente na instalação, crie um diretório e defina o caminho do símbolo usando esses comandos.
C:\> mkdir c:\symbols
C:\> set _NT_SYMBOL_PATH=srv*C:\symbols*https://msdl.microsoft.com/download/symbols
Este comando de exemplo exibe as principais funções do NT.
C:\> dtrace -n "fbt:nt:*Timer*:entry { @k[probefunc] = count(); } tick-5s { trunc(@k, 10);printa(@k); exit(0); }"
dtrace: description 'fbt:nt:*Timer*:entry ' matched 340 probes
CPU ID FUNCTION:NAME
0 22362 :tick-5s
KeCancelTimer 712
KeSetTimer2 714
HalpTimerClearProblem 908
ExpSetTimerObject 935
NtSetTimerEx 935
KeSetTimer 1139
KeSetCoalescableTimer 3159
KeResumeClockTimerFromIdle 11767
xHalTimerOnlyClockInterruptPending 22819
xHalTimerQueryAndResetRtcErrors 22819
Este comando despeja a estrutura do kernel SystemProcess.
C:\> dtrace -n "BEGIN {print(*(struct nt`_EPROCESS *) nt`PsInitialSystemProcess);exit(0);}"
...
uint64_t ParentSecurityDomain = 0
void *CoverageSamplerContext = 0
void *MmHotPatchContext = 0
union _PS_PROCESS_CONCURRENCY_COUNT ExpectedConcurrencyCount = {
Fraction :20 = 0
Count :12 = 0
uint32_t AllFields = 0
}
struct _KAFFINITY_EX IdealProcessorSets = {
uint16_t Count = 0x1
uint16_t Size = 0x20
uint32_t Reserved = 0
uint64_t [32] Bitmap = [ 0x1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
}
}
Este comando exibe a pilha do kernel superior nos últimos 10 segundos.
C:\> dtrace -qn "profile-997hz { @[stack()] = count(); } tick-10sec { trunc(@,5); printa(@); exit(0);}"
nt`KiDispatchInterruptContinue
nt`KiDpcInterrupt+0x318
nt`KiSwapThread+0x1054
nt`KiCommitThreadWait+0x153
nt`KeRemoveQueueEx+0x263
nt`IoRemoveIoCompletion+0x54
nt`NtWaitForWorkViaWorkerFactory+0x284
nt`KiSystemServiceCopyEnd+0x35
14
nt`KiDispatchInterruptContinue
nt`KiDpcInterrupt+0x318
...
Este comando exibe os principais módulos invocados por notepad.exe na inicialização. A opção -c executa o comando especificado (notepad.exe) e sai após a conclusão.
C:\> dtrace -qn "pid$target:::entry { @k[probemod] = count();} tick-10s{printa(@k); exit(0);}" -c notepad.exe
gdi32full 5
msvcp_win 6
combase 7
notepad 9
ADVAPI32 10
GDI32 11
SHELL32 11
USER32 21
win32u 345
KERNELBASE 3727
msvcrt 7749
KERNEL32 9883
RPCRT4 11710
ntdll 383445