Created
February 15, 2017 12:08
-
-
Save primiano/49be3aebd81e7a74e8034493da40667e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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