问题
I could find out the address of a buffer in memory trivially as follows :-
int main() {
char buffer[100];
printf("%p\n, buffer);
}
Is there any way I could print out the address of the page the buffer belongs to?
[EDIT] I'm on a Linux machine, Ubuntu to be exact. I'm curious about both 32 and 64 bit versions.
回答1:
There seems to be no system call provided by the Linux where we can get such information. However I think we can get the information(/proc directory) by following steps:
Get the buffer address assume 0x7fffffffe0b0(attach with gdb so that program would pause)
Execute the command(cat /proc/3586/maps)assume PID = 3586
Execute the command(cat /proc/3586/numa_maps)
Now following buffer address belongs to the [stack] segments below.
mantosh@mantosh4u:/proc/3586$ cat maps
00400000-00401000 r-xp 00000000 08:03 5116562 /home/mantosh/practice/bakwas
00600000-00601000 r--p 00000000 08:03 5116562 /home/mantosh/practice/bakwas
00601000-00602000 rw-p 00001000 08:03 5116562 /home/mantosh/practice/bakwas
7ffff7204000-7ffff72ff000 r-xp 00000000 08:03 23336063 /lib/x86_64-linux-gnu/libm-2.15.so
7ffff72ff000-7ffff74fe000 ---p 000fb000 08:03 23336063 /lib/x86_64-linux-gnu/libm-2.15.so
7ffff74fe000-7ffff74ff000 r--p 000fa000 08:03 23336063 /lib/x86_64-linux-gnu/libm-2.15.so
7ffff74ff000-7ffff7500000 rw-p 000fb000 08:03 23336063 /lib/x86_64-linux-gnu/libm-2.15.so
7ffff7500000-7ffff76b5000 r-xp 00000000 08:03 23334413 /lib/x86_64-linux-gnu/libc-2.15.so
7ffff76b5000-7ffff78b5000 ---p 001b5000 08:03 23334413 /lib/x86_64-linux-gnu/libc-2.15.so
7ffff78b5000-7ffff78b9000 r--p 001b5000 08:03 23334413 /lib/x86_64-linux-gnu/libc-2.15.so
7ffff78b9000-7ffff78bb000 rw-p 001b9000 08:03 23334413 /lib/x86_64-linux-gnu/libc-2.15.so
7ffff78bb000-7ffff78c0000 rw-p 00000000 00:00 0
7ffff78c0000-7ffff78d5000 r-xp 00000000 08:03 23331018 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff78d5000-7ffff7ad4000 ---p 00015000 08:03 23331018 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff7ad4000-7ffff7ad5000 r--p 00014000 08:03 23331018 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff7ad5000-7ffff7ad6000 rw-p 00015000 08:03 23331018 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff7ad6000-7ffff7bbc000 r-xp 00000000 08:03 1573341 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18
7ffff7bbc000-7ffff7dbb000 ---p 000e6000 08:03 1573341 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18
7ffff7dbb000-7ffff7dc3000 r--p 000e5000 08:03 1573341 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18
7ffff7dc3000-7ffff7dc5000 rw-p 000ed000 08:03 1573341 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18
7ffff7dc5000-7ffff7dda000 rw-p 00000000 00:00 0
7ffff7dda000-7ffff7dfc000 r-xp 00000000 08:03 23336064 /lib/x86_64-linux-gnu/ld-2.15.so
7ffff7fd2000-7ffff7fd7000 rw-p 00000000 00:00 0
7ffff7ff8000-7ffff7ffb000 rw-p 00000000 00:00 0
7ffff7ffb000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00022000 08:03 23336064 /lib/x86_64-linux-gnu/ld-2.15.so
7ffff7ffd000-7ffff7fff000 rw-p 00023000 08:03 23336064 /lib/x86_64-linux-gnu/ld-2.15.so
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
We can see the output from the last command mention above(numa_maps)
mantosh@mantosh4u:/proc/3586$ cat numa_maps
00400000 default file=/home/mantosh/practice/bakwas anon=1 dirty=1 N0=1
00600000 default file=/home/mantosh/practice/bakwas anon=1 dirty=1 N0=1
00601000 default file=/home/mantosh/practice/bakwas anon=1 dirty=1 N0=1
7ffff7204000 default file=/lib/x86_64-linux-gnu/libm-2.15.so mapped=16 mapmax=52 N0=16
7ffff72ff000 default file=/lib/x86_64-linux-gnu/libm-2.15.so
7ffff74fe000 default file=/lib/x86_64-linux-gnu/libm-2.15.so anon=1 dirty=1 N0=1
7ffff74ff000 default file=/lib/x86_64-linux-gnu/libm-2.15.so anon=1 dirty=1 N0=1
7ffff7500000 default file=/lib/x86_64-linux-gnu/libc-2.15.so anon=1 dirty=1 mapped=63 mapmax=111 N0=63
7ffff76b5000 default file=/lib/x86_64-linux-gnu/libc-2.15.so
7ffff78b5000 default file=/lib/x86_64-linux-gnu/libc-2.15.so anon=4 dirty=4 N0=4
7ffff78b9000 default file=/lib/x86_64-linux-gnu/libc-2.15.so anon=2 dirty=2 N0=2
7ffff78bb000 default anon=3 dirty=3 N0=3
7ffff78c0000 default file=/lib/x86_64-linux-gnu/libgcc_s.so.1 mapped=3 mapmax=22 N0=3
7ffff78d5000 default file=/lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff7ad4000 default file=/lib/x86_64-linux-gnu/libgcc_s.so.1 anon=1 dirty=1 N0=1
7ffff7ad5000 default file=/lib/x86_64-linux-gnu/libgcc_s.so.1 anon=1 dirty=1 N0=1
7ffff7ad6000 default file=/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18 mapped=90 mapmax=20 N0=90
7ffff7bbc000 default file=/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18
7ffff7dbb000 default file=/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18 anon=8 dirty=8 N0=8
7ffff7dc3000 default file=/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18 anon=2 dirty=2 N0=2
7ffff7dc5000 default anon=3 dirty=3 N0=3
7ffff7dda000 default file=/lib/x86_64-linux-gnu/ld-2.15.so anon=1 dirty=1 mapped=27 mapmax=106 N0=27
7ffff7fd2000 default anon=5 dirty=5 N0=5
7ffff7ff8000 default anon=3 dirty=3 N0=3
7ffff7ffb000 default
7ffff7ffc000 default file=/lib/x86_64-linux-gnu/ld-2.15.so anon=1 dirty=1 N0=1
7ffff7ffd000 default file=/lib/x86_64-linux-gnu/ld-2.15.so anon=2 dirty=2 N0=2
7ffffffdd000 default stack anon=2 dirty=2 N0=2
The more detailed information regarding each line entry can be found in proc and numa documentation. However our buffer belongs to the last entry which contains the information about the page and the base address and some other useful information(like dirty status of page and all). Hope this might be useful.
来源:https://stackoverflow.com/questions/22595265/find-which-page-an-address-belongs-to