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

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.

你可能感兴趣的:(C++,c,C#,bash)