Skip to content

Instantly share code, notes, and snippets.

@primiano
Created February 15, 2017 12:08
Show Gist options
  • Save primiano/49be3aebd81e7a74e8034493da40667e to your computer and use it in GitHub Desktop.
Save primiano/49be3aebd81e7a74e8034493da40667e to your computer and use it in GitHub Desktop.
#include <ctype.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <signal.h>
typedef void(*Callback)(uintptr_t /*start*/, unsigned long/*size*/, const char* /*prot flags*/, const char* /*fname*/, unsigned long /*pss*/);
void ForEachMapEntry(Callback callback) {
FILE* f = fopen("/proc/self/smaps", "r");
unsigned long start = 0, end = 0;
char mapped_file[512] = {};
char prot[5] = {};
while(!feof(f)) {
char line[512];
fgets(line, sizeof(line), f);
if (isxdigit(line[0])) {
sscanf(line, "%lx-%lx %s %*s %*s %*s %[^\n]\n", &start, &end, prot, mapped_file);
} else if(strncmp(line, "Pss:", 4) == 0) {
int pss = 0;
sscanf(line, "Pss: %d kB", &pss);
callback(start, end-start, prot, mapped_file, pss);
}
}
fclose(f);
}
unsigned long g_total_pss;
void CalcTotalPSS(uintptr_t start, unsigned long size, const char* prot, const char* mapped_file, unsigned long pss) {
//printf("%s %s %lu\n", prot, mapped_file, pss);
g_total_pss += pss;
}
void PrintSelfPSS() {
g_total_pss = 0;
ForEachMapEntry(CalcTotalPSS);
printf("Total PSS: %lu kB\n", g_total_pss);
}
void DropRXPages(uintptr_t start, unsigned long size, const char* prot, const char* mapped_file, unsigned long pss) {
if (strncmp(prot, "r-x", 3) == 0)
madvise((void*)start, size, MADV_DONTNEED);
}
void FaultRXPages(uintptr_t start, unsigned long size, const char* prot, const char* mapped_file, unsigned long pss) {
volatile int total = 0;
if (strncmp(prot, "r-x", 3) == 0) {
unsigned long s;
for (s = 0; s < size; s += sizeof(int))
total += *((int*)(start + s));
}
}
void sighandler(int _) {
printf("Madvising all R-X pages\n");
ForEachMapEntry(DropRXPages); // Drop all r-x pages.
PrintSelfPSS();
}
int main(int argcv, char** argv) {
// Page faulting on all r-x mapped files to gather some PSS.
ForEachMapEntry(FaultRXPages);
PrintSelfPSS();
signal(SIGUSR2, sighandler);
for(;;) sleep(60);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment