Реализация Solaris pmap
фактически доступна в виде исходного кода через OpenSolaris, pmap.c
.Но это очень сложная вещь;основы проще достичь.
В Solaris есть три /proc
маркеров для карт:
/proc/<PID>/map
, в которых содержится struct prmap
данные, которые отражают «обычный» размер рабочего набора /proc/<PID>/rmap
, который также содержит данные struct prmap
, но для размера виртуального набора (VSZ), то есть отражают диапазоны сопоставленных VA, даже если сопоставление не зафиксировано. /proc/<PID>/xmap
, который содержит struct prxmap
данные, которые фактически перелистывают адресное пространство для идентификации резидентных областей памяти.
Утилита pmap
выглядитв них, когда вы передаете либо без аргументов (map
), -r
(rmap
) или -x
(xmap
), но, как вы обнаружили, это гораздо больше, чем просто открытие / чтение картыфайлы proc.Во многом это затрудняет анализ исходного кода.
Тем не менее, вы можете создать тривиальный Solaris [rx]map
(используйте struct prxmap
вместо struct prmap
, если вы обращаетесь, конечно, к xmap
) с помощью кода, подобного:
char mappath[MAXPATHLEN];
sprintf(mappath, "/proc/%d/map", getpid());
int fd = open(mappath, O_RDONLY);
size_t nread;
size_t mapsz = (1 << 20); /* start at 1MB */
struct prmap *cur*mapbuf = malloc(mapsz);
while ((nread = pread(fd, mapbuf, mapsz, 0)) == mapsz) {
free(mapbuf);
mapsz *= 2;
mapbuf = malloc(mapsz);
}
for (cur = mapbuf; nread; cur++, nread -= sizeof(*mapbuf))
prettyprint(cur);
free(mapbuf);
Несколько подсказок:
- не пытайтесь
mmap()
файл map
, который не будет работать (procfs не разрешает это) - не пытайтесь последовательно читать его части;вышеупомянутое (перечитывание целого из начала в измененный размер буфера) на быстрее , чем выполнение непрерывной последовательности
read()
.Всегда читайте с начала (используйте pread
, как в примере, или lseek(..., 0, SEEK_SET)
перед любым read
).
Наслаждайтесь экспериментами!
Редактировать:
Поскольку вы решили найти имена путей для сопоставлений, это одна из действительно сложных задач.pmap
не занимается этим сам, но использует средства libproc
для разрешения этих имен, которые, как вы обнаружили в truss
, могут перетаскивать адресное пространство процесса для их извлечения, но также используютнесколько других техник.По сути это "iter" функции в libproc/Psymtab.c
, которые делают это.Также есть различия между Solaris 9 и более поздними версиями ... не помню, слишком давно ...