static void fix_numiptent(ub_param *ub) { unsigned long min_ipt; if (ub->numiptent == NULL) return; min_ipt = min_ul(ub->numiptent[0], ub->numiptent[1]); if (min_ipt < MIN_NUMIPTENT) { logger(-1, 0, "Warning: NUMIPTENT %lu:%lu is less" " than minimally allowable value, set to %d:%d", ub->numiptent[0], ub->numiptent[1], MIN_NUMIPTENT, MIN_NUMIPTENT); ub->numiptent[0] = MIN_NUMIPTENT; ub->numiptent[1] = MIN_NUMIPTENT; } }
static void pmaps(int pid, print_flags_t pflags, regex_t *regex, int fd_kflags, int fd_kcount) { FILE *maps = NULL; int fd_p=-1; unsigned long start_addr, end_addr; char *line=0; size_t line_n=0; maps = fopen(proc_fn(pid, "maps"), "r"); if (!maps) { fprintf(stderr, "ERROR: could not open /proc/%d/maps: %s\n", pid, strerror(errno)); goto done; } fd_p = open(proc_fn(pid, "pagemap"), O_RDONLY); if (fd_p<0) { fprintf(stderr, "ERROR: could not open /proc/%d/pagemap: %s\n", pid, strerror(errno)); goto done; } while (1) { int ret = getline(&line, &line_n, maps); if (ret == -1) { goto done; } if (pflags & STACK_ONLY) { if (strstr(line, "[stack]") == NULL) continue; } else if (pflags & HEAP_ONLY) { if (strstr(line, "[heap]") == NULL) continue; } else if (regex) { if (regexec(regex, line, 0, NULL, 0) != 0) continue; } if (sscanf(line, "%lx-%lx", &start_addr, &end_addr) != 2) { (void) fprintf(stderr, "ERROR: did not understand line from /proc/pid/maps. :(\n"); goto done; } (void) printf("%s", line); unsigned long page_start = start_addr / pagesize; unsigned long page_end = end_addr / pagesize; x_lseek(fd_p, sizeof(uint64_t)*page_start, SEEK_SET); unsigned long nr_read = 0; unsigned long nr_read_total = 0; for (; page_start < page_end; page_start += BSIZE, nr_read_total += nr_read) { nr_read = min_ul(page_end-page_start, BSIZE); if (read(fd_p, pagemap, nr_read*sizeof(uint64_t)) != (ssize_t)(nr_read*sizeof(uint64_t))) { // Reading the /proc/pid/pagemap entry for // /proc/pid/maps [vsyscall] resulted in zero // byte reads. Let's just ignore such cases. continue; } populate(fd_kflags, pageflags, nr_read); populate(fd_kcount, pagecount, nr_read); for (unsigned i=0; i < nr_read; ++i) { if (PMAP_PRESENT&pagemap[i] && !(pflags & SWAPPED_ONLY)) { printf(" %#lx -> pfn:%#08llx count:%4llu flags:%s\n", start_addr + (nr_read_total+i)*pagesize, PMAP_PFN&pagemap[i], (unsigned long long)pagecount[i], flags2str(pageflags[i])); } else if (PMAP_SWAPPED&pagemap[i] && !(pflags & RESIDENT_ONLY)) { printf(" #%#lx -> swaptype:%#llx swapoff:%#08llx\n", start_addr + (nr_read_total+i)*pagesize, PMAP_SWAP_TYPE&pagemap[i], (PMAP_SWAP_OFF&pagemap[i])>>5); } else if (!(pflags & (SWAPPED_ONLY|RESIDENT_ONLY))) { printf(" !%#lx\n", start_addr + (nr_read_total+i)*pagesize); } } }