Compartilhar via


Depuração do código gerenciado usando o depurador do Windows

Você pode usar os depuradores do Windows (WinDbg, CDB e NTSD) para depurar aplicativos de destino que contêm código gerenciado. Para depurar o código gerenciado, use a extensão de depuração !SOS (sos.dll) e um componente de acesso a dados (mscordacwks.dll) em combinação com o tempo de execução de CLR.

Os depuradores do Windows, como o WinDbg, são separados do depurador do Visual Studio. Para obter informações sobre a distinção entre os depuradores do Windows e o depurador do Visual Studio, confira Ferramentas de depuração para Windows.

Este artigo fornece instruções sobre como usar depuradores do Windows (WinDbg, CDB, NTSD) para depurar código gerenciado, incluindo aplicativos .NET Framework, .NET Core e .NET 5+.

Observação

Ao depurar aplicativos .NET Framework, .NET Core e .NET 5+, verifique se você está usando a versão mais recente das ferramentas do depurador do Windows. Além disso, considere usar o Visual Studio ou o Visual Studio Code para obter uma experiência de depuração mais integrada. O WinDbg é mais complexo, dá mais trabalho para configurar e normalmente é usado quando informações adicionais de baixo nível são necessárias.

Introdução ao código gerenciado

O código gerenciado é executado junto com o CLR (Tempo de execução de linguagem comum) do Microsoft .NET. Em um aplicativo de código gerenciado, o código binário que o compilador produz está na MSIL (Linguagem intermediária da Microsoft), que é independente de plataforma.

Quando o código gerenciado é executado, o tempo de execução produz código nativo específico da plataforma. O processo de geração de código nativo do MSIL é chamado de compilação JIT (just-in-time) . Depois que o compilador JIT compilar o MSIL para um método específico, o código nativo do método permanecerá na memória. Sempre que esse método for chamado posteriormente, o código nativo será executado e o compilador JIT não precisará estar envolvido.

Você pode criar código gerenciado usando vários compiladores fabricados por uma variedade de produtores de software. Em particular, o Microsoft Visual Studio pode criar código gerenciado de várias linguagens diferentes, incluindo C#, Visual Basic, JScript e C++ com extensões gerenciadas.

O CLR não é atualizado sempre que o .NET Framework é atualizado. Por exemplo, as versões 2.0, 3.0 e 3.5 do .NET Framework usam, todas, a versão 2.0 do CLR. Para obter mais informações sobre as versões do .NET, confira Versões e dependências do .NET Framework. Para obter informações sobre como determinar a versão do .NET em seu computador, confira Determinar quais versões do .NET Framework estão instaladas.

Depurando código gerenciado

Para depurar o código gerenciado usando a extensão de depuração !SOS, o depurador deve carregar vários componentes. A extensão de depuração !SOS e os componentes necessários que são usados são diferentes para o .NET Core e o .NET Framework original. Para ambos, o DAC (Componente de acesso a dados) (mscordacwks.dll) é usado.

O SDK do .NET fornece ferramentas que podem ser úteis para trabalhar com a depuração de aplicativos .NET. Para obter mais informações, confira O que é SDK do .NET?.

.NET Core

Para o .NET Core, há uma ferramenta CLI dotnet disponível para instalar !sos.dll. Para saber mais, confira Instalador do SOS (dotnet-sos).

O .NET Framework original.

Obtendo a extensão de depuração SOS (sos.dll)

Os arquivos de extensão de depuração SOS (sos.dll) não estão incluídos em todas as versões das ferramentas de depuração para Windows. Se sos.dll não estiver disponível, confira Instalando o SOS no Windows.

Carregando a extensão de depuração SOS (sos.dll)

Para depurar aplicativos .NET Core e .NET 5+, você precisa carregar a versão apropriada da extensão de depuração SOS.

Por exemplo, para uma versão de ! SOS incluída no depurador e incluída no caminho de pesquisa de extensão atual, o comando .load seria usado.

0:000> .load sos.dll

Para verificar se a extensão de depuração SOS foi carregada corretamente, use o comando .chain e exmaine a cadeia DLL da extensão.

...
Extension DLL chain:
    C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll: image 4.8.9275.0, API 1.0.0, built Wed Aug 28 14:43:27 2024
        [path: C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll]
    C:\Program Files (x86)\dotnet\shared\Microsoft.NETCore.App\8.0.8\coreclr.dll: image 8,0,824,36612 @Commit: 08338fcaa5c9b9a8190abb99222fed12aaba956c, built Tue Jul 16 11:10:19 2024
        [path: C:\Program Files (x86)\dotnet\shared\Microsoft.NETCore.App\8.0.8\coreclr.dll]

Se a versão do depurador não incluir o sos.dll, talvez seja necessário especificar o caminho completo para o arquivo SOS.dll. Normalmente, você pode encontrar o arquivo SOS.dll no diretório de tempo de execução da instalação do .NET Core ou do .NET Framework.

0:000> .load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll

Carregando uma versão específica do sos.dll

Carregar o sos.dll pode ser complexo, pois há uma dependência das DLLs adicionais, que são usadas pelo sos.dll para se comunicar com o .NET. Além disso, a versão da DLL necessária depende da versão do .NET do aplicativo que está sendo depurado e várias versões do .NET podem estar presentes no computador.

Uma estratégia para carregar a versão correta da DLL dependente é solicitar que o depurador inicie quando a primeira notificação (CLRN) do .NET clr ocorrer usando o sx, sxd, sxe, sxi, sxn, sxr, sx- (Definir exceções)[.. /debuggercmds/sx--sxd--sxe--sxi--sxn--sxr--sx---set-exceptions-.md]. Depois de anexar ao aplicativo .NET de destino, esse comando será usado após a primeira entrada.

0:000> sxe CLRN

Em seguida, retome a execução e aguarde a entrada ocorrer.

0:000> g

Quando a entrada ocorrer, desabilite a entrada de notificação clr, pois sabemos que a clr.dll (ou coreclr.dll) foi carregada.

0:000> sxd CLRN

Com o depurador nesse contexto, use o .loadby para carregar o !sos do mesmo local de diretório "próximo".

0:000> .loadby sos clr

Outra opção é usar a .cordll (depuração CLR de controle) para carregar as DLLs de depuração CLR fornecendo um caminho para o local da estrutura de destino.

0:000> .cordll -ve -u -lp C:\Windows\Microsoft.NET\Framework\v4.0.30319\
CLRDLL: Loaded DLL C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscordacwks.dll
Automatically loaded SOS Extension
CLR DLL status: Loaded DLL C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscordacwks.dll

Usando a extensão de depuração SOS

Para verificar se a extensão de depuração SOS foi carregada corretamente, insira o comando .chain .

0:000> .chain
Extension DLL search Path:
    C:\Program Files\Debugging Tools for Windows (x64);...
Extension DLL chain:
    C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll: image 4.8.9275.0, API 1.0.0, built Wed Aug 28 14:43:27 2024
        [path: C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll]
...

Arquivos de símbolos .NET

Os arquivos de símbolos são essenciais para a depuração. Para aplicativos .NET Framework, .NET Core e .NET 5+, você pode recuperar os arquivos de símbolos necessários do servidor de símbolos públicos da Microsoft. Use o comando a seguir para definir o caminho do símbolo e o carregamento do símbolo de eco.

.symfix

!sym noisy

.reload

Testando a extensão !sos do .NET Core

Para testar a extensão de depuração SOS, insira !sos.help.

0:000> !sos.help
-------------------------------------------------------------------------------
SOS is a debugger extension DLL designed to aid in the debugging of managed
programs. Functions are listed by category, then roughly in order of
importance. Shortcut names for popular functions are listed in parenthesis.
Type "!help <functionname>" for detailed info on that function. 

Object Inspection                  Examining code and stacks
-----------------------------      -----------------------------
DumpObj (do)                       Threads
DumpArray (da)                     ThreadState
DumpStackObjects (dso)             IP2MD
DumpHeap                           U
DumpVC                             DumpStack
GCRoot                             EEStack
ObjSize                            CLRStack
FinalizeQueue                      GCInfo
PrintException (pe)                EHInfo
TraverseHeap                       BPMD 
                                   COMState

Em seguida, tente um dos comandos fornecidos pela extensão de depuração SOS. Por exemplo, você poderia tentar o comando !sos.DumpDomain ou o comando !sos.Threads fornecido pela extensão de depuração SOS .NET Core.

0:000> !sos.DumpDomain
--------------------------------------
System Domain:      7565d980
LowFrequencyHeap:   7565dca4
HighFrequencyHeap:  7565dcf0
StubHeap:           7565dd3c
Stage:              OPEN
Name:               None
--------------------------------------
Shared Domain:      7565d620
LowFrequencyHeap:   7565dca4
HighFrequencyHeap:  7565dcf0
StubHeap:           7565dd3c
Stage:              OPEN
Name:               None
Assembly:           00fa5e78 [C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
ClassLoader:        00fa5f40
  Module Name
73571000    C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll

0:000> !sos.Threads
ThreadCount:      2
UnstartedThread:  0
BackgroundThread: 2
PendingThread:    0
DeadThread:       0
Hosted Runtime:   no
                                                                         Lock  
       ID OSID ThreadOBJ    State GC Mode     GC Alloc Context  Domain   Count Apt Exception
   0    1 4538 00f91110     20220 Preemptive  02FE1238:00000000 00f58be0 1     Ukn 
   7    2 250c 00f9da88     21220 Cooperative 00000000:00000000 00f58be0 1     Ukn (Finalizer) 

Testando a extensão !sos do .NET Framework

Para testar a extensão de depuração SOS, insira !sos.help. Em seguida, tente um dos comandos fornecidos pela extensão de depuração SOS. Por exemplo, você pode tentar o comando !sos.sostatus ou o comando !sos.threads .

0:030> !soshelp
crashinfo                                 Displays the crash details that created the dump.
help, soshelp <command>                   Displays help for a command.
loadsymbols <url>                         Loads symbols for all modules.
logclose <path>                           Disables console file logging.
logging <path>                            Enables/disables internal diagnostic logging.
logopen <path>                            Enables console file logging.
maddress                                  Displays a breakdown of the virtual address space.
modules, lm                               Displays the native modules in the process.
registers, r                              Displays the thread's registers.
runtimes <id>                             Lists the runtimes in the target or changes the default runtime.
setclrpath <path>                         Sets the path to load coreclr DAC/DBI files.
setsymbolserver, SetSymbolServer <url>    Enables and sets symbol server support for symbols and module download.
sosflush                                  Resets the internal cached state.
sosstatus                                 Displays internal status.
threads, setthread <thread>               Lists the threads in the target or sets the current thread.

Observações

Às vezes, um aplicativo de código gerenciado carrega mais de uma versão do CLR. Nesse caso, você deve especificar qual versão do DAC carregar. Para obter mais informações, confira .cordll e Clrver.exe (ferramenta de versão CLR).