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.
Habilitar a visualização NATVIS do Linux e a travessia de link DML
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 kdump
o .
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.