Skip to content

Instantly share code, notes, and snippets.

@ozanh
Forked from hillu/dump-pagemap.c
Created March 11, 2021 10:34
Show Gist options
  • Save ozanh/249592787f7e866f67eafedeb7268563 to your computer and use it in GitHub Desktop.
Save ozanh/249592787f7e866f67eafedeb7268563 to your computer and use it in GitHub Desktop.
/*
dump-pagemap.c - Dump pagemap entries associated with mappings of a given process
Copyright 2021 Hilko Bengen <bengen@hilluzination.de>
License: GPL3 or later
Based on information from:
- linux/Documentation/filesystems/proc.txt
- linux/Documentation/admin-guide/mm/pagemap.rst
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
int main(int argc, char** argv) {
if (argc != 2) {
fprintf(stderr, "usage: %s <pid>\n pid = numeric PID or \"self\"\n", argv[0]);
exit(1);
}
char filebuf[256];
snprintf(filebuf, sizeof(filebuf), "/proc/%s/maps", argv[1]);
FILE* maps = fopen(filebuf, "r");
if (maps == NULL) {
fprintf(stderr, "open: %s: %s\n", filebuf, strerror(errno));
exit(1);
}
snprintf(filebuf, sizeof(filebuf), "/proc/%s/pagemap", argv[1]);
int pagemap = open(filebuf, O_RDONLY);
if (pagemap == -1) {
fprintf(stderr, "open: %s: %s\n", filebuf, strerror(errno));
exit(1);
}
uint64_t pagesize = sysconf(_SC_PAGE_SIZE);
char line[1024];
while (fgets(line, sizeof(line), maps)) {
uint64_t begin, end;
sscanf(line, "%" SCNx64 "-%" SCNx64, &begin, &end);
fputs(line, stdout);
printf("map: %"PRIx64"-%"PRIx64" (%"PRIx64")\n", begin, end, end-begin);
for (uint64_t pos = begin; pos < end; pos = pos + pagesize) {
uint64_t entry;
int sz = pread(pagemap, &entry, sizeof(entry), (pos / pagesize) * sizeof(entry));
if (sz != 8) {
fprintf(stderr, "pread\n");
exit(1);
}
// bit 61: present
// bit 62: file-backed
// bit 63: shared
fputc(".fsx:FSX"[entry >> 61], stdout);
}
fputc('\n', stdout);
}
fclose(maps);
close(pagemap);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment