Кодирование pmap в Solaris - PullRequest
       9

Кодирование pmap в Solaris

2 голосов
/ 02 ноября 2011

В настоящее время я пытаюсь написать свою собственную программу, которая отражает команду pmap, особенно в Solaris 9. У меня проблемы с разрешением имен и путей библиотек.Вывод команды Solaris выглядит примерно так из оболочки bash:

bash-2.05# pmap $$
2427:   bash
00010000     496K r-x--  /usr/bin/bash
0009A000      80K rwx--  /usr/bin/bash
000AE000     120K rwx--    [ heap ]
FF100000     688K r-x--  /usr/lib/libc.so.1
FF1BC000      24K rwx--  /usr/lib/libc.so.1
FF1C2000       8K rwx--  /usr/lib/libc.so.1
FF200000     568K r-x--  /usr/lib/libnsl.so.1
FF29E000      32K rwx--  /usr/lib/libnsl.so.1
FF2A6000      32K rwx--  /usr/lib/libnsl.so.1
FF2F0000       8K rwx--    [ anon ]
FF300000      16K r-x--  /usr/lib/libmp.so.2
FF314000       8K rwx--  /usr/lib/libmp.so.2
FF320000       8K r-x--  /usr/platform/sun4u-us3/lib/libc_psr.so.1
FF330000      40K r-x--  /usr/lib/libsocket.so.1
FF34A000       8K rwx--  /usr/lib/libsocket.so.1
FF350000     168K r-x--  /usr/lib/libcurses.so.1
FF38A000      32K rwx--  /usr/lib/libcurses.so.1
FF392000       8K rwx--  /usr/lib/libcurses.so.1
FF3A0000       8K r-x--  /usr/lib/libdl.so.1
FF3B0000       8K rwx--    [ anon ]
FF3C0000     152K r-x--  /usr/lib/ld.so.1
FF3F6000       8K rwx--  /usr/lib/ld.so.1
FFBFC000      16K rw---    [ stack ]
 total      2536K

В основном я могу дублировать основные функции программы, читая / proc / $$ / map, но остается только выяснить как разрешить имена библиотек , показанные справа./ proc / $$ / map дает только имена файлов в / proc / $$ / object, которые являются просто общими именами.В Solaris 10 (окно у меня есть) я, кажется, могу использовать / proc / $$ / path, который содержит символические ссылки, но в окне, над которым я работаю, их нет.Есть ли у кого-нибудь простые идеи о том, как получить эти имена библиотек?Когда я запускаю программу, она, кажется, открывает / proc / $$ / as, просматривает память и каким-то образом находит их, но я пока не могу понять, где она выглядит и почему.

1 Ответ

2 голосов
/ 10 ноября 2011

Реализация Solaris pmap фактически доступна в виде исходного кода через OpenSolaris, pmap.c.Но это очень сложная вещь;основы проще достичь.

В Solaris есть три /proc маркеров для карт:

  1. /proc/<PID>/map, в которых содержится struct prmap данные, которые отражают «обычный» размер рабочего набора
  2. /proc/<PID>/rmap, который также содержит данные struct prmap, но для размера виртуального набора (VSZ), то есть отражают диапазоны сопоставленных VA, даже если сопоставление не зафиксировано.
  3. /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 и более поздними версиями ... не помню, слишком давно ...

...