Deixe-me iniciar uma pergunta dizendo que encontrei muitas respostas para perguntas semelhantes à minha pergunta, mas para máquinas de 32 bits. No entanto, não consigo encontrar nada para máquinas de 64 bits. Por favor, não há respostas em relação às máquinas de 32 bits.
De acordo com muitas fontes no Stack Exchange, /proc/kcore
pode ser literalmente despejado (por exemplo, com dd
) em um arquivo para obter uma cópia da memória física ... Mas isso claramente não funciona para um 64 máquina de bits, para a qual /proc/kcore
tem 128TB de tamanho.
Como um aparte, noto que é possível acessar apenas o primeiro MB de memória através de /dev/mem
. Isto é por razões de segurança. Contornar isso envolve recompilar o kernel, o que eu não quero fazer ... nem posso fazer para meus propósitos (tenho que trabalhar com o kernel em execução).
Ok ... então, /proc/kcore
é um arquivo ELF-core da memória física e pode ser visualizado usando gdb
. Por exemplo, com:
gdb /usr/[blah]/vmlinux /proc/kcore
Isso eu posso fazer ... mas, isso não é o que eu quero fazer. Eu gostaria de exportar a memória física para um arquivo para análise offline. Mas estou correndo em problemas.
Por um lado, não posso simplesmente copiar /proc/kcore
para um arquivo, já que é 128 TB. Eu quero despejar toda a memória física, mas eu não sei onde está em /proc/kcore
. Eu só vejo dados não-zero até o byte 3600 e, em seguida, são todos zeros, tanto quanto eu olhei (cerca de 40GB). Acho que isso pode ter a ver com a forma como a memória é mapeada para /proc/kcore
, mas não entendo a estrutura e preciso de orientação.
Mais coisas que eu acho que sei: eu sei que apenas 48 bits são usados para endereçamento, não 64 bits. Isto implica que deve haver 2 48 = 256TB de memória disponível ... mas /proc/kcore
é apenas 128TB, o que é eu acho porque o endereçamento é dividido em um pedaço de 0x0000000000000000 para 0x00007fffffffffff (128TB) e um pedaço de 0xffff800000000000 para 0xffffffffffffffff (128TB). Então, de alguma forma isso faz /proc/kcore
128TB ... mas isso é porque um desses pedaços é mapeado para /proc/kcore
e um não é? Ou algum outro motivo?
Como exemplo, posso usar gdb
para analisar /proc/kcore
e encontrar, por exemplo, a localização (?) da sys_call_table:
(gdb) p (unsigned long*) sys_call_table
$1 = (unsigned long *) 0xffffffff811a4f20 <sys_read>
Isso significa que o pedaço de memória de 0xffff8000000000000 para 0xffffffffffffffff é o que está em /proc/kcore
? E se sim, como isso é mapeado para /proc/kcore
? Por exemplo, usando
dd if=/proc/kcore bs=1 skip=2128982200 count=100 | xxd
mostra apenas zeros (2128982200 é um pouco antes 0xffffffffffffffff-0xffffffff811a4f20) ...
Além disso, sei como usar gcore
para despejar a memória de um determinado processo para análise. E eu também sei que posso olhar em /proc/PID/maps
para ver como é a memória do processo ... mas mesmo assim eu ainda não tenho idéia de como descarregar toda a memória física ... e é meio que me deixando louco. Por favor me ajude a evitar ficar louco ...;)