Program to Display a Virtual Address Map /* The program below will display the virtual address map of a given process. Available via anonymous FTP on ftp.sgi.com in the directory ~ftp/support/Pipeline. Compile and run it as follows: cc dpa.c -o dpa; ./dpa pid ( where pid is the process id of a process which can obtained from the ps(1) command. ) */ #include "stdio.h" #include "stdlib.h" #include "sys/procfs.h" #include "fcntl.h" #include "errno.h" static void doname(char *pname); prmap_sgi_t *pmaps; #define MAXMAP 2000 int maxmap = MAXMAP; /* set of page state options */ char *stateopts[] = { "READ", "WRITE", "EXEC", "SHARED", "BREAK", "STACK", "PHYS", "PRIMARY", "SREGION", "COW", "NOTCACHED", "SHMEM" }; /* MA_* flags that correspond to above options */ int maopts[] = { MA_READ, MA_WRITE, MA_EXEC, MA_SHARED, MA_BREAK, MA_STACK, MA_PHYS, MA_PRIMARY, MA_SREGION, MA_COW, MA_NOTCACHED, MA_SHMEM }; void main(int argc, char **argv) { pid_t pid = -1; char pname[20]; if(argc!=2) { fprintf(stderr, "Usage: %s pid\n", \ argv[0]); exit(1); } pid = (pid_t)atoi(argv[1]); pmaps = malloc((maxmap + 1) * sizeof(prmap_t)); sprintf(pname, "/proc/%05d", pid); doname(pname); exit(0); } static void doname(char *pname) { int pfd; struct prpsinfo psi; struct prmap_sgi_arg pma; int nmaps; prmap_sgi_t *pmapp; if ((pfd = open(pname, O_RDWR)) < 0) { if (errno == EISDIR || errno == ESRCH || \ errno == ENOENT) return; if (errno != EACCES) fprintf(stderr, "ERROR:Cannot open \ %s:%s\n", pname, strerror(errno)); return; } if (ioctl(pfd, PIOCPSINFO, &psi) != 0) { if (errno != ESRCH) fprintf(stderr, "ERROR:Cannot PSINFO \ %s:%s\n", pname, strerror(errno)); close(pfd); return; } printf("pid %d, ",psi.pr_pid); if (psi.pr_zomb == 0) { pma.pr_vaddr = (caddr_t)pmaps; pma.pr_size = sizeof(prmap_sgi_t) * maxmap; if ((nmaps = ioctl(pfd, PIOCMAP_SGI, \ &pma)) < 0) { fprintf(stderr, "ERROR:Cannot NMAP_SGI \ %s:%s\n", pname, strerror(errno)); close(pfd); return; } printf("process has %d regions\n", nmaps); } if (psi.pr_zomb == 0) { printf("addr\t\tsize\t\t off\t\tflags\n"); printf("----\t\t----\t\t ---\t\t-----\n"); for (pmapp = pmaps; pmapp->pr_mflags; \ pmapp++) { printf("0x%x\t0x%x\t\t0x%x\t\t", \ pmapp->pr_vaddr, pmapp->pr_size, \ pmapp->pr_off); printf("%s%s%s%s%s%s%s%s%s%s%s%s\n", pmapp->pr_mflags & MA_READ ? " READ" : "", pmapp->pr_mflags & MA_WRITE ? \ " WRITE" : "", pmapp->pr_mflags & MA_EXEC ? " EXEC" : "", pmapp->pr_mflags & MA_SHARED ? \ " SHARED" : "", pmapp->pr_mflags & MA_BREAK ? \ " BREAK" : "", pmapp->pr_mflags & MA_STACK ? \ " STACK" : "", pmapp->pr_mflags & MA_PHYS ? " PHYS" : "", pmapp->pr_mflags & MA_PRIMARY ? \ " PRIMARY" : "", pmapp->pr_mflags & MA_SREGION ? \ " SREGION" : "", pmapp->pr_mflags & MA_COW ? " COW" : "", pmapp->pr_mflags & MA_NOTCACHED? \ " NOTCACHED":"", pmapp->pr_mflags & MA_SHMEM ? \ " SHMEM" : ""); } } else printf(" Process is a zombie\n"); close(pfd); }