MDB: virtual and physical memory map for both kernel and application

本文介绍如何使用 mdb 工具从用户空间进程的虚拟地址获取对应的物理地址,并读取其内容。通过示例代码展示了从虚拟地址到物理地址转换的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

virtual and physical memory map

We can use ::vtop and "\" (format from physical instead of virtual) to retrieve the physical address and content of a virtual address.

# mdb -k
...
> rootfs/s
rootfs:
rootfs: zfs
> rootfs::vtop
virtual fffffffffbc00f48 mapped to physical a400f48
> a400f48\s
0xa400f48: zfs

Things will be a little complexed if we want to make this for a virutal address in application address.

Here is a segment of code to print the virtual address and content of a application pointer.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MSG "Hello, World!"

int main(int argc, char* argv[])
{
int length = strlen(MSG);
char* message = malloc(length + 1);
memcpy(message, MSG, length);
message[length + 1] = 0;

unsigned int address = (unsigned int) message;

printf("Message is: %s\n", message);
printf("Address is: %x\n", address);

getchar();

free(message);

return EXIT_SUCCESS;
}

bash-3.00# cc -g -o test test.c
bash-3.00# ./test
Message is: Hello, World!
Address is: 8060e90

If you want to translate the virtual address 8060e90 to the physical address with mdb. It is ok, when you just run mdb and print string by virtual address:

bash-3.00# mdb -p `ps -a | pgrep test`
Loading modules: [ ld.so.1 libc.so.1 ]
> 8060e90/s
0x8060e90: Hello, World!

But neither "::vtop", nor "\" works.

> 8060e90::vtop
mdb: failed to get physical mapping: operation not supported by target
> 8060e90\s
mdb: failed to read data from target: operation not supported by target
0x8060e90:

Those won't work when attached to a process; the process model doesn't export that. You'll have to run MDB against the live kernel and do it from there:

% cat > tmpc.c <<EOF
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MSG "Hello, World!"

int
main(int argc, char *argv[])
{
char *message = strdup(MSG);

printf("Message: \"%s\" (0x%p)\n", message, message);

getchar();

return (0);
}
EOF
% cc -o tmpc tmpc.c
% ./tmpc & sleep 1
[2] 101948
* note the PID
Message: "Hello, World!" (0x8061128)
* note the virtual address address
[2] + 101948 suspended (tty input) ./tmpc
% su
Password:
# mdb -k
* attach to the running kernel
Loading modules: [ ... ]
> 0t101948::pid2proc
* uses the pid ("0t" indicates decimal)
ffffff0527e33398
> 0t101948::pid2proc | ::print proc_t p_as
p_as = 0xffffff01eca01d00
* this gives the "address space" (as) for the process
> 0x8061128::vtop -a 0xffffff01eca01d00
virtual 8061128 mapped to physical 331a1128
* Now we can print the string from the physical page
> 331a1128\s
0x331a1128: Hello, World!
>

Okay, we've made it.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值