Compartilhar via


Despejos de memória do Linux

Este artigo descreve como criar e exibir diferentes tipos de arquivos de despejo de memória do Linux. A exibição de despejos de memória do Linux requer o WinDbg versão 1.2402.24001.0 ou superior.

Ao abrir um despejo de memória do Linux (não Windows) no WinDbg, os comandos básicos do depurador devem funcionar corretamente, mas as extensões e os comandos específicos do Windows que fazem referência a estruturas do Windows não funcionarão.

Arquivos de despejo de memória suportados

Despejos de kernel do Linux

Abrir KDUMPs compactados do kernel do Linux e fazer depuração e análise post-mortem com símbolos DWARF privados completos está disponível no depurador Windows.

O WinDbg dá suporte apenas a arquivos KDUMP compactados com ZLIB. Os KDUMPs compactados LZO e Snappy não são suportados.

Para obter informações gerais sobre KDUMPs do Linux, consulte a página da Wikipédia do KDump (Linux) e o despejo principal.

Despejos de núcleo ELF

Como parte do suporte ao Open Enclave, o WinDbg pode abrir despejos de memória e binários ELF, bem como símbolos DWARF (não há suporte para DWARF 5) de aplicativos Enclaves e Linux. Para obter mais informações sobre o Open Enclave, consulte Depuração do Open Enclave.

Despejos de processo

Há suporte para despejos de processo únicos. Há várias maneiras de coletar um despejo de processo, incluindo o utilitário Linux Sysinternals ProcDump para Linux . Outra opção é usar o GNU Debugger - GDBServer, para gerar um core dump. Para obter mais informações sobre GDBServer, consulte https://en.wikipedia.org/wiki/Gdbserver. A documentação para depuração remota do gdb está disponível no site do Sourceware - Depurando Programas Remotos.

A extensibilidade da STL (Biblioteca de Modelos Padrão) nos Depuradores do Windows é fornecida por um arquivo NatVis, stl.natvis que entende muitas versões da STL fornecidas com o Visual Studio e o Windows. Para obter informações gerais sobre o NATVIS, consulte Objetos nativos do depurador no NatVis. As versões do STL que são usadas para componentes Linux (GCC ou LLDB) são muito diferentes.

Para habilitar a visualização NATVIS e a travessia de link DML otimizada para Linux, primeiro descarregue o arquivo natvis padrão, .scriptunload stl.natvis.

Em seguida, .scriptcarregue o gstl.natvis arquivo. Use .scriptlist para confirmar se gstl.natvis está ativo.

0: kd> .scriptlist
Command Loaded Scripts:
...
    NatVis script from 'C:\Users\Bob\AppData\Local\dbg\UI\2402.24001.0\amd64\Visualizers\gstl.natvis'

Para obter mais informações sobre como trabalhar com DML, consulte Personalizando a saída do depurador usando DML.

Despejo de núcleo de processo único do aplicativo DisplayGreeting

Este exemplo mostra como criar um único dump de núcleo de processo usando gdb. Para obter mais informações sobre como usar o GDBServer com o WinDbg e um passo a passo do código, consulte Depuração de processo remoto ao vivo do Linux. Para obter o código de exemplo para DisplayGreeting, consulte Passo a passo do aplicativo C++.

Localize o processo desejado

Podemos listar todos os processos no Linux usando o ps -A comando ou usar a opção -f com pgrep, pois sabemos que estamos procurando o aplicativo DisplayGreeting.

$ pgrep -f DisplayGreeting
9382

Neste passo a passo de exemplo, ele mostra uma ID de processo de 9382.

Anexar ao processo com gdb e gerar um despejo de memória

Use gdb para anexar ao processo.

$ gdb -p 9382

Exibir ajuda para o generate-core-file comando gdb.

(gdb) help generate-core-file
Save a core file with the current state of the debugged process.
Argument is optional filename.  Default filename is 'core.<process_id>'.

Em seguida, no prompt (gdb), gere um arquivo de despejo principal do processo com o nome de arquivo padrão.

(gdb) generate-core-file
Saved corefile core.9382
(gdb) quit

Carregar e examinar o despejo de memória do processo do Linux

Use a opção de menu Abrir arquivo de despejo no WinDbg para carregar o despejo principal gerado.

Adicionar os caminhos de origem e símbolo à sessão do depurador

Para exibir o código-fonte e as variáveis, defina os símbolos e o caminho de origem. Para obter informações gerais sobre como definir o caminho dos símbolos, confira Usar símbolos. Para obter informações mais detalhadas sobre símbolos do Linux, consulte Símbolos e fontes do Linux.

Use .sympath para adicionar o caminho do símbolo à sessão do depurador. Neste exemplo do WSL Linux Ubuntu, o código e os símbolos DisplayGreetings estão disponíveis neste local, para um usuário chamado Bob.

\\wsl$\Ubuntu\mnt\c\Users\Bob\

No WSL, esse diretório é mapeado para o local do sistema operacional Windows de: C:\Users\Bob\ Portanto, esses dois comandos são usados.

.sympath C:\Users\Bob\

.srcpath C:\Users\Bob\

Para obter mais informações sobre como acessar o sistema de arquivos WSL no Windows, consulte Permissões de arquivo para WSL.

Para se beneficiar de símbolos adicionais do sistema operacional Linux, adicione os símbolos DebugInfoD usando o local .sympath.

.sympath+ DebugInfoD*https://debuginfod.elfutils.org

Use o .reload comando para recarregar os símbolos.

Também há suporte para o download automático de fontes de servidores DebugInfoD, que dão suporte ao retorno desse tipo de artefato. Para aproveitar esse recurso, adicione o servidor elfutils usando .srcpath.

.srcpath+ DebugInfoD*https://debuginfod.elfutils.org

Examinando o despejo de processo

Use o lm comando para confirmar se o arquivo de despejo contém o aplicativo DisplayGreeting.

0:000> lm
start             end                 module name
00005555`55554000 00005555`55558140   DisplayGreeting T (service symbols: DWARF Private Symbols)        c:\users\bob\DisplayGreeting
00007fff`f7a54000 00007fff`f7a732e8   libgcc_s_so   (deferred)    
00007fff`f7a74000 00007fff`f7b5a108   libm_so    (deferred)    
00007fff`f7b5b000 00007fff`f7d82e50   libc_so  T (service symbols: DWARF Private Symbols)        C:\ProgramData\Dbg\sym\_.debug\elf-buildid-sym-a43bfc8428df6623cd498c9c0caeb91aec9be4f9\_.debug
00007fff`f7d83000 00007fff`f7fae8c0   libstdc___so   (deferred)    
00007fff`f7fc1000 00007fff`f7fc1000   linux_vdso_so   (deferred)    
00007fff`f7fc3000 00007fff`f7ffe2d8   ld_linux_x86_64_so T (service symbols: DWARF Private Symbols)        C:\ProgramData\Dbg\sym\_.debug\elf-buildid-sym-9718d3757f00d2366056830aae09698dbd35e32c\_.debug

Observe que a execução do primeiro comando pode levar um pouco de tempo, pois os símbolos de depuração são carregados no cache. Além de procurar símbolos e binários por meio do servidor de símbolos ou do caminho de pesquisa local, devido à integração do GDBServer, ele pode carregar esses arquivos de um sistema de arquivos remoto se eles não puderem ser encontrados localmente. Essa operação geralmente é mais lenta do que adquirir símbolos do symsrv ou de um caminho de pesquisa local.

Use o x comando para exibir as funções disponíveis em DisplayGreeting.

0:000> x /D /f DisplayGreeting!*
 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

*** WARNING: Unable to verify timestamp for DisplayGreeting
00005651`7935b331 DisplayGreeting!_GLOBAL__sub_I__Z17GetCppConGreetingPwm (void)
00005651`7935b2db DisplayGreeting!__static_initialization_and_destruction_0 (int, int)
00005651`7935b37b DisplayGreeting!std::__array_traits<wchar_t, 50>::_S_ptr (wchar_t (*)[50])
00005651`7935b368 DisplayGreeting!std::array<wchar_t, 50>::size (std::array<wchar_t, 50> *)
00005651`7935b34a DisplayGreeting!std::array<wchar_t, 50>::data (std::array<wchar_t, 50> *)
00005651`7935b225 DisplayGreeting!main (void)
00005651`7935b1e9 DisplayGreeting!GetCppConGreeting (wchar_t *, size_t)

Use o dx comando para exibir a saudação da variável local.

0:000> dx greeting
...
Error: Unable to bind name 'greeting'

Como a saudação de parâmetro ainda não foi usada quando o despejo foi feito, ela não está disponível no arquivo de despejo.

Use o dx comando para examinar os processos que estão disponíveis no arquivo de despejo.

:000> dx @$cursession.Processes.Take(30)
@$cursession.Processes.Take(30)                
    [0x24a6]         : DisplayGreeting [Switch To]

Click on the `[Switch To]` DML link to switch to the 9382 process.

```dbgcmd
0:000> dx -s @$cursession.Processes.Take(30)[9382].SwitchTo()
0:000> dx -r1 @$cursession.Processes.Take(30)[9382]
@$cursession.Processes.Take(30)[9382]                 : DisplayGreeting [Switch To]
    Name             : DisplayGreeting
    Id               : 0x24a6
    Index            : 0x0
    Handle           : 0x24a6
    Threads         
    Modules         
    Environment     
    Direct3D        
    Attributes      
    Devices         
    Io              
    Memory          
    TTD    
    GroupedStacks   

Para exibir informações sobre os threads e módulos, clique no link DML gerado na saída ou digite comandos semelhantes a este para o despejo de memória.

0:000> dx -r1 @$cursession.Processes.Take(30)[9382].Threads
@$cursession.Processes.Take(30)[9382].Threads       
    [0x24a6]         [Switch To]
0:000> dx -r1 @$cursession.Processes.Take(30)[9382].Modules
@$cursession.Processes.Take(30)[9382].Modules       
    [0x0]            : /mnt/c/Users/Bob/DisplayGreeting
    [0x1]            : /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
    [0x2]            : /usr/lib/x86_64-linux-gnu/libm.so.6
    [0x3]            : /usr/lib/x86_64-linux-gnu/libc.so.6
    [0x4]            : /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.30
    [0x5]            : /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    [0x6]            : linux-vdso.so.1

Usar as extensões de diagnóstico ELF/CORE para exibir informações do arquivo de despejo

Use as extensões de diagnóstico do Linux - ELFBinComposition.dll para exibir informações do arquivo de despejo. Por exemplo, use !dumpdebug para confirmar que este é um despejo de memória do usuário ELF e exibir outras informações.

0:000> !dumpdebug
Dump Diagnostics: Format = ELF User Core
********************************************************************************
File Mapping Size:           0x151d78 (1 Mb)
Highest Memory Offset:       0x14e5f0 (1 Mb)
...

Use !ntprpsinfo para exibir os dados NT_PRPSINFO.

0:000> !ntprpsinfo
NT_PRPSINFO (process info):
    state: 0, sname: t, zomb: 0, nice: 0, flag: 0x4040000019999999
    uid: 1000, gid: 1000, pid: 9382, ppid: 388, pgrp: 9382, sid: 388
    fname: DisplayGreeting
    psargs: ./DisplayGreeting

Despejos de memória do kernel KDump

Há muitas maneiras de criar um arquivo de despejo de memória no Linux. Por exemplo, uma opção com o Ubuntu Linux é descrita em Despejo de memória do kernel.

Outras opções incluem o uso de kexectools para habilitar o Kdump. Para mais informações, veja KDump (Linux). Se o kdump estiver ativado, você poderá verificar se o kdump está ativo e em execução usando systemctl status kdumpo .

Depois que a falha do sistema operacional é acionada em um sistema de teste, o arquivo de despejo de memória é criado.

Carregar e examinar o despejo de memória do sistema operacional Linux

Use a opção de menu Abrir arquivo de despejo para carregar o kdump gerado.

Conforme descrito na seção anterior, habilite a visualização NATVIS e a passagem de link DML otimizada para Linux, carregando o gstl.natvis arquivo.

Use os comandos de composição ELF Bin para analisar um despejo de kernel do Linux

Para poder usar comandos adicionais de composição ELF Bin, use o comando .chain para confirmar se o ELFBinComposition.dll está carregado.

0: kd> .chain
Extension DLL chain:
    ELFBinComposition: image 10.0.27606.1000, API 0.0.0, 
        [path: C:\Users\Bob\AppData\Local\dbg\UI\Fast.20240423.1\amd64\winext\ELFBinComposition.dll]
...

Se ELFBinComposition não estiver carregado, use .load para carregá-lo. Para obter mais informações, consulte .load, .loadby (DLL de extensão de carga)

Use o !ELFBinComposition.dumpdebug comando para exibir informações sobre o arquivo de despejo carregado. Neste exemplo, um arquivo de despejo principal do usuário ELF foi carregado.

0: kd> !ELFBinComposition.dumpdebug
Dump Diagnostics: Format = Kernel KDump
********************************************************************************
File Mapping Size:           0x3b34090 (59 Mb)
Highest Memory Offset:       0x3b34090 (59 Mb)

Use ELFBinComposition !vmcoreinfo para exibir a tabela VMCOREINFO do despejo de memória do kernel do Linux (KDUMP) que está sendo depurado.

0: kd> !vmcoreinfo
VMCOREINFO:
    OSRELEASE=6.5.0-25-generic
    BUILD-ID=8567ad7c7c2f78f3654f6cc90a9e1b3f9c3a4b32
    PAGESIZE=4096
    SYMBOL(init_uts_ns)=ffffded86e11b388
    OFFSET(uts_namespace.name)=0
    SYMBOL(node_online_map)=ffffded86dcceb40
    SYMBOL(swapper_pg_dir)=ffffded86d143000
    SYMBOL(_stext)=ffffded86ace0000
    SYMBOL(vmap_area_list)=ffffded86de48140
    SYMBOL(mem_section)=ffff0f2e1efe4600
    LENGTH(mem_section)=8192
...

Use o !kdumppagerange para despejar a primeira parte do arquivo de despejo, começando em zero.

0: kd> !kdumppagerange 0
    PFNs [0x540e0, 0x55643) -> Descs [0x0, 0x1563): File Offsets [0x307430, 0xeeb37a) 0xbe3f4a bytes across 5475 pages as ZLIB
    PFNs [0x55643, 0x55650) -> Descs [0x1563, 0x1570): File Offsets [0x306430, 0x307430) 0x1000 bytes across 13 duplicate pages as Uncompressed
    PFNs [0x55650, 0x556d6) -> Descs [0x1570, 0x15f6): File Offsets [0xeeb37a, 0xf0c405) 0x2108b bytes across 134 pages as ZLIB
    PFNs [0x556d6, 0x556dc) -> Descs [0x15f6, 0x15fc): File Offsets [0xf0c405, 0xf12405) 0x6000 bytes across 6 pages as Uncompressed
    PFNs [0x556dc, 0x55e98) -> Descs [0x15fc, 0x1db8): File Offsets [0xf12405, 0x1216d1b) 0x304916 bytes across 1980 pages as ZLIB
    PFNs [0x55e98, 0x55ea4) -> Descs [0x1db8, 0x1dc4): File Offsets [0x1216d1b, 0x1222d1b) 0xc000 bytes across 12 pages as Uncompressed
    PFNs [0x55ea4, 0x56542) -> Descs [0x1dc4, 0x2462): File Offsets [0x1222d1b, 0x14ba138) 0x29741d bytes across 1694 pages as ZLIB
    PFNs [0x56542, 0x56543) -> Descs [0x2462, 0x2463): File Offsets [0x306430, 0x307430) 0x1000 bytes across 1 pages as Uncompressed
    PFNs [0x56543, 0x56544) -> Descs [0x2463, 0x2464): File Offsets [0x14ba138, 0x14ba194) 0x5c bytes across 1 pages as ZLIB
    PFNs [0x56544, 0x5654f) -> Descs [0x2464, 0x246f): File Offsets [0x306430, 0x307430) 0x1000 bytes across 11 duplicate pages as Uncompressed

A saída de !kdumppagerange exibe vários valores de PFN (quadro de página). Podemos selecionar um de interesse e usar o !kdumppfn <PFN> para exibir informações sobre o PFN e onde seus dados estão dentro do KDUMP.

0: kd> !kdumppfn 0x540e0
    Page frame 0x540e0 = File offset [0x307430, 0x307b9f) 0x76f bytes as ZLIB...

Examinar o arquivo de despejo

Use o k comando para exibir a pilha de chamadas para investigar qual código estava em execução quando a falha ocorreu.

6: kd> k
 # Child-SP          RetAddr               Call Site
00 ffff0000`0bc3bc90 ffff0000`085161f8     vmlinux!sysrq_handle_crash+0x24 [/usr/src/kernel/drivers/tty\sysrq.c @ 147] 
01 ffff0000`0bc3bca0 ffff0000`08516824     vmlinux!__handle_sysrq+0x88 [/usr/src/kernel/drivers/tty\sysrq.c @ 583] 
02 ffff0000`0bc3bcb0 ffff0000`08308990     vmlinux!write_sysrq_trigger+0xb4 [/usr/src/kernel/drivers/tty\sysrq.c @ 1110] 
03 ffff0000`0bc3bcf0 ffff0000`08290070     vmlinux!proc_reg_write+0x80 [/usr/src/kernel/fs/proc\inode.c @ 245] 
04 ffff0000`0bc3bd10 ffff0000`0829039c     vmlinux!__vfs_write+0x60 [/usr/src/kernel/fs\read_write.c @ 490] 
05 ffff0000`0bc3bd50 ffff0000`08290704     vmlinux!vfs_write+0xac [/usr/src/kernel/fs\read_write.c @ 550] 
06 ffff0000`0bc3be00 ffff0000`082907a4     vmlinux!ksys_write+0x74 [/usr/src/kernel/fs\read_write.c @ 599] 
07 (Inline Function) --------`--------     vmlinux!__do_sys_write+0xc [/usr/src/kernel/fs\read_write.c @ 608] 
08 (Inline Function) --------`--------     vmlinux!__se_sys_write+0xc [/usr/src/kernel/fs\read_write.c @ 608] 
09 ffff0000`0bc3be40 ffff0000`08095904     vmlinux!__arm64_sys_write+0x24 [/usr/src/kernel/fs\read_write.c @ 608] 
0a ffff0000`0bc3be90 ffff0000`080834c8     vmlinux!el0_svc_handler+0x94
0b ffff0000`0bc3beb0 00000000`00000000     vmlinux!el0_svc+0x8

Use o dx comando para examinar o arquivo de despejo. Por exemplo, observe os primeiros 30 processos usando este comando.

6: kd> dx @$cursession.Processes.Take(30)
@$cursession.Processes.Take(30)                
    [0x0]            : swapper/0 [Switch To]
    [0x1]            : systemd [Switch To]
    [0x2]            : kthreadd [Switch To]
    [0x3]            : rcu_gp [Switch To]
    [0x4]            : rcu_par_gp [Switch To]
    [0x5]            : kworker/0:0 [Switch To]
    [0x6]            : kworker/0:0H [Switch To]
    [0x7]            : kworker/u16:0 [Switch To]
    [0x8]            : mm_percpu_wq [Switch To]
    [0x9]            : ksoftirqd/0 [Switch To]
    [0xa]            : rcu_sched [Switch To]
    [0xb]            : rcu_bh [Switch To]
    [0xc]            : migration/0 [Switch To]
...

Clique nos links DML ou use comandos semelhantes a este para examinar os threads em um processo de interesse.

6: kd> dx @$cursession.Processes[0x1a].Threads
@$cursession.Processes[0x1a].Threads                
    [0x1a]           [Switch To]
6: kd> dx @$cursession.Processes[0x1a].Threads[0x1a]
@$cursession.Processes[0x1a].Threads[0x1a]                 [Switch To]
    KernelObject     [Type: thread_struct]
    Id               : 0x1a
    Stack           
    Registers       
    Environment     
    Analysis        
    WaitChain       
    Scheduling      
    IRPs            
...

Informações adicionais para cada thread estão disponíveis, conforme mostrado abaixo.

6: kd> dx @$cursession.Processes[0x1a].Threads[0x1a].KernelObject
@$cursession.Processes[0x1a].Threads[0x1a].KernelObject                 [Type: thread_struct]
    [+0x000] cpu_context      [Type: cpu_context]
    [+0x070] uw               [Type: <unnamed-tag>]
    [+0x290] fpsimd_cpu       : 0x100 [Type: unsigned int]
    [+0x298] sve_state        : 0x0 [Type: void *]
    [+0x2a0] sve_vl           : 0x0 [Type: unsigned int]
    [+0x2a4] sve_vl_onexec    : 0x0 [Type: unsigned int]
    [+0x2a8] fault_address    : 0x0 [Type: long unsigned int]
    [+0x2b0] fault_code       : 0x0 [Type: long unsigned int]
    [+0x2b8] debug            [Type: debug_info]
6: kd> dx -s @$cursession.Processes[0x1a].Threads[0x1a].SwitchTo()
Process ffff8008`0f894380 has invalid page directories

Usar o script LinuxKernel.js para analisar um despejo de kernel do Linux

A extensão do depurador LinuxKernel.js contém um conjunto de comandos projetados para funcionar de forma semelhante aos encontrados no utilitário de falha do Linux que é usado para abrir e analisar falhas no modo kernel do Linux.

Para usar o script, primeiro carregue o script.

0: kd> .scriptload LinuxKernel.js
JavaScript script successfully loaded from 'C:\Users\Bob\AppData\Local\dbg\UI\Fast.20240423.1\amd64\winext\LinuxKernel.js'

Para obter mais informações sobre como trabalhar com scripts de carregamento, consulte Scripts do depurador JavaScript.

!limas

Use o !files para exibir informações sobre a estrutura de arquivos do Linux no arquivo de despejo. É semelhante ao comando de arquivos de falha.

6: kd> !files
@$files()                 : Files for process 'sh' (pid 545) root dir = '/' working dir = '/home/root'
    [0x0]            : /dev/ttyS0 [Type: file]
    [0x1]            : /proc/sysrq-trigger [Type: file]
    [0x2]            : /dev/ttyS0 [Type: file]
    [0xa]            : /dev/ttyS0 [Type: file]
    [0xff]           : /dev/ttyS0 [Type: file]

Sintaxe !files:

!files [<arg>]

Sem [<arg>]- Equivalente a 'arquivos' - fornece a lista de arquivos do processo atual

[<arg>]:

pid - Fornece a lista de arquivos para o ID do processo fornecido

64-bit num - Fornece a lista de arquivos para a tarefa no endereço fornecido

<task struct [*]> - Fornece a lista de arquivos para a tarefa dada struct por objeto

<process object> - Fornece a lista de arquivos para a tarefa representada pelo objeto de processo

!montar

Use o !mount para exibir informações sobre a estrutura de arquivos do Linux no arquivo de despejo.

6: kd> !mount
@$mount()                
    [0x0]            : (rootfs) rootfs at / [Type: mount]
    [0x1]            : (squashfs) /dev/mapper/nested_rootfs at / [Type: mount]
    [0x2]            : (sysfs) sysfs at /sys [Type: mount]
    [0x3]            : (proc) proc at /proc [Type: mount]
    [0x4]            : (devtmpfs) devtmpfs at /dev [Type: mount]
    [0x5]            : (securityfs) securityfs at /kernel/security [Type: mount]

Sintaxe !mount:

Sem [<arg>]- Equivalente ao comando 'mount' - mostra os sistemas de arquivos montados

[<arg>]:

pid - Fornece os sistemas de arquivos montados para namespace do processo com o pid fornecido

64-bit num - Fornece os sistemas de arquivos montados para o namespace do task_struct fornecido por endereço

<task struct [*]> - Fornece os sistemas de arquivos montados para o namespace do task_struct fornecido

<process object> - Fornece os sistemas de arquivos montados para o namespace da tarefa representada pelo processo

!rede

Use o !net para exibir a lista de redes do sistema.

6: kd> !net
@$net()                
    [0x0]            : lo (127.0.0.1) [Type: net_device]
    [0x1]            : enP8p1s0f0np0 (192.168.3.19) [Type: net_device]
    [0x2]            : enP8p1s0f1np0 [Type: net_device]

Sintaxe !net:

!net [<arg>]

Sem [<arg>]- Equivalente a 'net' - fornece a lista de redes do sistema

[<arg>]:

pid - Fornece a lista de rede para namespace do processo com o pid fornecido

64-bit num - Fornece a lista de rede para o namespace do task_struct fornecido por endereço

<task struct [*]> - Fornece a lista de rede para o namespace do task_struct fornecido

<process object> - Fornece a lista de redes para o namespace da tarefa representada pelo processo

!runq

Use o !runq para exibir informações sobre as tarefas na fila de execução.

0: kd> !runq
@$runq()                
    [0x0]            : CPU 0 run queue [current = 'bash' (17ca)]
        Cpu              : 0x0
        RunQueue         [Type: rq]
        CurrentTask      : bash [Type: task_struct]
        RTTasks         
        CfsTasks        
            [0x16b3]         : kworker/0:7 [Type: task_struct]
    [0x1]            : CPU 1 run queue [current = 'swapper/1' (0)]
        Cpu              : 0x1
        RunQueue         [Type: rq]
        CurrentTask      : swapper/1 [Type: task_struct]
        RTTasks         
        CfsTasks   

Sintaxe !runq:

!runq

!runq não tem nenhum parâmetro de comando.

Comandos adicionais de despejo de kernel

!dev - Exibe dados do dispositivo sobre o caractere e o dispositivo de bloco, atribuições, uso da porta de E/S, uso da memória de E/S.

!log - Exibe o conteúdo do kernel log_buf.

!vm - Exibe um resumo do uso da memória virtual.

!timer - Exibe as entradas da fila do temporizador.

comando dx e objetos Linux

O comando dx pode ser usado para investigar kdumps. Exiba o objeto Sessions para ver os vários objetos filho disponíveis.

0: kd> dx -r3 Debugger.Sessions[0]
Debugger.Sessions[0]                 : Target Composition Target
    Processes       
        [0x0]            : swapper/0 [Switch To]
            KernelObject     : swapper/0 [Type: task_struct]
            Name             : swapper/0
            Id               : 0x0
            Index            : 0x0
            Threads         
            Modules         
            Environment     
            Direct3D        
            Attributes      
            Devices         
            Io              
            Memory          
            GroupedStacks   
...

O objeto Kernel cursession contém o objeto PrintKLog que pode ser usado para exibir o log do kernel.

6: kd> dx @$cursession.Kernel.PrintKLog.Take(4)
@$cursession.Kernel.PrintKLog.Take(4)                
    [0x0]            : [     0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd083]
    [0x1]            : [     0.000000] Linux version 4.19.90-microsoft-standard (oe-user@oe-host) (gcc version 8.2.0 (GCC)) #1 SMP Fri Mar 27 14:25:24 UTC 2020..
    [0x2]            : [     0.000002] sched_clock: 64 bits at 125MHz, resolution 8ns, wraps every 4398046511100ns
    [0x3]            : [     0.000003]         17.250901928 MSFT: kernel boot start

Este comando dx mostra o uso de .Contains() para procurar strings específicas no log.

6: kd> dx @$cursession.Kernel.PrintKLog.Where(le => le.ToLower().Contains("oops") || le.ToLower().Contains("crash"))
@$cursession.Kernel.PrintKLog.Where(le => le.ToLower().Contains("oops") || le.ToLower().Contains("crash"))                
    [0x0]            : [     0.000493] crashkernel reserved: 0x00000000dc600000 - 0x00000000fc600000 (512 MB)
    [0x1]            : [     0.078790] Kernel command line: console=ttyS0,115200n8 earlycon=uart8250,mmio32,0x68A10000 crashkernel=512M enforcing=0 ipe.enforce=0
    [0x2]            : [    26.621228] sysrq: SysRq : Trigger a crash
    [0x3]            : [    26.621254] Internal error: Oops: 96000044 [#1] SMP
    [0x4]            : [    26.656655] pc : sysrq_handle_crash+0x24/0x30
    [0x5]            : [    26.753494]  sysrq_handle_crash+0x24/0x30
    [0x6]            : [    26.801441] Starting crashdump kernel...8J»=.

Use .Reverse() para mostrar os últimos eventos registrados.

2: kd> dx @$cursession.Kernel.PrintKLog.Reverse().Take(5).Reverse()
@$cursession.Kernel.PrintKLog.Reverse().Take(5).Reverse()
   [0x0]           : [3147944.378367]  kthread+0x118/0x2a4
   [0x1]           : [3147944.381876]  ret_from_fork+0x10/0x18
   [0x2]           : [3147944.385747] Code: 78002507 36000042 39000107 d65f03c0 (cb0803e4)
   [0x3]           : [3147944.392221] SMP: stopping secondary CPUs
   [0x4]           : [3147944.397539] Starting crashdump kernel...

Para obter mais informações sobre como usar consultas LINQ com o comando dx, consulte Usando LINQ com os objetos do depurador.

Extensões de diagnóstico do Linux - ELFBinComposition.dll

As seguintes extensões de diagnóstico de arquivo de despejo do Linux estão disponíveis no ELFBinComposition.dll.

Comandos de arquivo de despejo

Esses comandos podem ser usados na maioria dos arquivos de despejo.

!dumpdebug - Exiba diagnósticos para o despejo de memória que está sendo depurado. Isso inclui a saída de vários outros comandos.

!ntprstatus - Exiba os registros NT_PRSTATUS do despejo principal que está sendo depurado.

!vmcoreinfo - Exiba a tabela VMCOREINFO do despejo principal do kernel (KDUMP) que está sendo depurado.

Comandos de despejo ELF

Esses comandos só podem ser usados em arquivos de dump principal ELF.

!corephdrs - Exiba a tabela de cabeçalho do programa para o despejo de memória que está sendo depurado.

!ntprpsinfo - Exiba os dados NT_PRPSINFO do despejo principal que está sendo depurado.

!ntfile - Exiba os dados NT_FILE do despejo principal que está sendo depurado.

!ntauxv - Exiba os dados NT_AUXV do despejo de memória que está sendo depurado.

Comandos do arquivo de despejo de memória do kernel

Esses comandos podem ser usados somente em arquivos de despejo de núcleo do kernel (KDUMP).

!kdumpdescs - Exibir a lista de intervalos de páginas e descritores de página em um KDUMP.

!kdumppagerange <n> - Exibir informações sobre o enésimo agrupamento de páginas no KDUMP.

!kdumppfn <pfn> - Exibir informações sobre o quadro <pfn> da página e onde seus dados estão dentro do KDUMP.

Outros comandos de diagnóstico

!cppex - Exibe informações sobre as exceções C++ atuais em andamento (não capturadas e "apenas" capturadas) para o thread atual, usando as estruturas internas da libstdc++ e os símbolos DWARF.

!cppfilt [-n] <mangled name> - Desfaz um nome mutilado em C++ como se ele fosse executado por meio da ferramenta c++filt. Para obter mais informações sobre a ferramenta C==filtr, consulte c++filt(1) — página de manual do Linux.

!rustdemangle <mangled name> - Desmembra um nome mutilado de Rust. Para obter mais informações sobre a mutilação do nome do símbolo de ferrugem, consulte Mutilação do símbolo de ferrugem – RFC 2603.

Confira também

Símbolos e fontes do Linux

Depuração de processo remota ao vivo do Linux