library: exploit linux-4.5 resident memory enhancement
Beginning with linux-4.5, the following new fields are
being added under that /proc/<pid>/status pseudo file:
. RssAnon - size of resident anonymous memory
. RssFile - size of resident file mappings
. RssShmem - size of resident shared memory
This patch just represents the initial library and top
support, sharing a commit message with 2 more patches.
p.s. locked resident memory support was also added but
isn't directly related to the kernel 4.5 enhancements.
Reference(s):
commit 1f8e41d019
Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
parent
b921e2e765
commit
8dc378f6a8
@ -242,6 +242,10 @@ REG_set(VM_EXE, ul_int, vm_exe)
|
||||
REG_set(VM_LIB, ul_int, vm_lib)
|
||||
REG_set(VM_LOCK, ul_int, vm_lock)
|
||||
REG_set(VM_RSS, ul_int, vm_rss)
|
||||
REG_set(VM_RSS_ANON, ul_int, vm_rss_anon)
|
||||
REG_set(VM_RSS_FILE, ul_int, vm_rss_file)
|
||||
REG_set(VM_RSS_LOCKED, ul_int, vm_lock)
|
||||
REG_set(VM_RSS_SHARED, ul_int, vm_rss_shared)
|
||||
REG_set(VM_SIZE, ul_int, vm_size)
|
||||
REG_set(VM_STACK, ul_int, vm_stack)
|
||||
REG_set(VM_SWAP, ul_int, vm_swap)
|
||||
@ -493,6 +497,10 @@ static struct {
|
||||
{ RS(VM_LIB), f_status, NULL, QS(ul_int), 0, -1 },
|
||||
{ RS(VM_LOCK), f_status, NULL, QS(ul_int), 0, -1 },
|
||||
{ RS(VM_RSS), f_status, NULL, QS(ul_int), 0, -1 },
|
||||
{ RS(VM_RSS_ANON), f_status, NULL, QS(ul_int), 0, -1 },
|
||||
{ RS(VM_RSS_FILE), f_status, NULL, QS(ul_int), 0, -1 },
|
||||
{ RS(VM_RSS_LOCKED), f_status, NULL, QS(ul_int), 0, -1 },
|
||||
{ RS(VM_RSS_SHARED), f_status, NULL, QS(ul_int), 0, -1 },
|
||||
{ RS(VM_SIZE), f_status, NULL, QS(ul_int), 0, -1 },
|
||||
{ RS(VM_STACK), f_status, NULL, QS(ul_int), 0, -1 },
|
||||
{ RS(VM_SWAP), f_status, NULL, QS(ul_int), 0, -1 },
|
||||
|
@ -132,6 +132,10 @@ enum pids_item {
|
||||
PROCPS_PIDS_VM_LIB, // ul_int
|
||||
PROCPS_PIDS_VM_LOCK, // ul_int
|
||||
PROCPS_PIDS_VM_RSS, // ul_int
|
||||
PROCPS_PIDS_VM_RSS_ANON, // ul_int
|
||||
PROCPS_PIDS_VM_RSS_FILE, // ul_int
|
||||
PROCPS_PIDS_VM_RSS_LOCKED, // ul_int
|
||||
PROCPS_PIDS_VM_RSS_SHARED, // ul_int
|
||||
PROCPS_PIDS_VM_SIZE, // ul_int
|
||||
PROCPS_PIDS_VM_STACK, // ul_int
|
||||
PROCPS_PIDS_VM_SWAP, // ul_int
|
||||
|
149
proc/readproc.c
149
proc/readproc.c
@ -113,7 +113,7 @@ static inline void free_acquired (proc_t *p, int reuse) {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct status_table_struct {
|
||||
unsigned char name[7]; // /proc/*/status field name
|
||||
unsigned char name[8]; // /proc/*/status field name
|
||||
unsigned char len; // name length
|
||||
#ifdef LABEL_OFFSET
|
||||
long offset; // jump address offset
|
||||
@ -129,8 +129,11 @@ typedef struct status_table_struct {
|
||||
#endif
|
||||
#define NUL {"", 0, 0},
|
||||
|
||||
#define GPERF_TABLE_SIZE 128
|
||||
|
||||
// Derived from:
|
||||
// gperf -7 --language=ANSI-C --key-positions=1,3,4 -C -n -c <if-not-piped>
|
||||
// ( --key-positions verified by omission & reported "Computed positions" )
|
||||
//
|
||||
// Suggested method:
|
||||
// Grep this file for "case_", then strip those down to the name.
|
||||
@ -144,8 +147,8 @@ typedef struct status_table_struct {
|
||||
// the F macro and replacing empty strings with the NUL define.
|
||||
//
|
||||
// In the status_table_struct watch out for name size (grrr, expanding)
|
||||
// and the number of entries (we mask with 63 for now). The table
|
||||
// must be padded out to 64 entries, maybe 128 in the future.
|
||||
// and the number of entries. Currently, the table is padded to 128
|
||||
// entries and we therefore mask with 127.
|
||||
|
||||
static void status2proc(char *S, proc_t *restrict P, int is_proc){
|
||||
long Threads = 0;
|
||||
@ -155,78 +158,76 @@ static void status2proc(char *S, proc_t *restrict P, int is_proc){
|
||||
// 128 entries because we trust the kernel to use ASCII names
|
||||
static const unsigned char asso[] =
|
||||
{
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 28, 64,
|
||||
64, 64, 64, 64, 64, 64, 8, 25, 23, 25,
|
||||
6, 25, 0, 3, 64, 64, 3, 64, 25, 64,
|
||||
20, 1, 1, 5, 0, 30, 0, 0, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 3, 64, 0,
|
||||
0, 18, 64, 10, 64, 10, 64, 64, 64, 20,
|
||||
64, 20, 0, 64, 25, 64, 3, 15, 64, 0,
|
||||
30, 64, 64, 64, 64, 64, 64, 64
|
||||
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
|
||||
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
|
||||
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
|
||||
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
|
||||
101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
|
||||
101, 101, 101, 101, 101, 101, 101, 101, 6, 101,
|
||||
101, 101, 101, 101, 101, 45, 55, 25, 31, 50,
|
||||
50, 10, 0, 35, 101, 101, 21, 101, 30, 101,
|
||||
20, 36, 0, 5, 0, 40, 0, 0, 101, 101,
|
||||
101, 101, 101, 101, 101, 101, 101, 30, 101, 15,
|
||||
0, 1, 101, 10, 101, 10, 101, 101, 101, 25,
|
||||
101, 40, 0, 101, 0, 50, 6, 40, 101, 1,
|
||||
35, 101, 101, 101, 101, 101, 101, 101
|
||||
};
|
||||
|
||||
static const status_table_struct table[] = {
|
||||
static const status_table_struct table[GPERF_TABLE_SIZE] = {
|
||||
F(VmHWM)
|
||||
NUL NUL
|
||||
F(VmLck)
|
||||
NUL
|
||||
F(VmSwap)
|
||||
F(VmRSS)
|
||||
NUL
|
||||
F(VmStk)
|
||||
NUL
|
||||
F(Tgid)
|
||||
F(State)
|
||||
NUL
|
||||
F(VmLib)
|
||||
NUL
|
||||
F(VmSize)
|
||||
F(SigQ)
|
||||
NUL
|
||||
F(SigIgn)
|
||||
NUL
|
||||
F(VmPTE)
|
||||
F(FDSize)
|
||||
NUL
|
||||
F(SigBlk)
|
||||
NUL
|
||||
F(ShdPnd)
|
||||
F(VmData)
|
||||
NUL
|
||||
F(CapInh)
|
||||
NUL
|
||||
F(PPid)
|
||||
NUL NUL
|
||||
F(CapBnd)
|
||||
NUL
|
||||
F(SigPnd)
|
||||
NUL NUL
|
||||
F(VmPeak)
|
||||
NUL
|
||||
F(SigCgt)
|
||||
NUL NUL
|
||||
F(Threads)
|
||||
NUL
|
||||
F(CapPrm)
|
||||
NUL NUL
|
||||
F(Pid)
|
||||
NUL
|
||||
F(CapEff)
|
||||
NUL NUL
|
||||
NUL NUL NUL
|
||||
F(VmRSS)
|
||||
F(VmSwap)
|
||||
NUL NUL NUL
|
||||
F(Tgid)
|
||||
F(VmStk)
|
||||
NUL NUL NUL
|
||||
F(VmSize)
|
||||
F(Gid)
|
||||
NUL
|
||||
F(VmExe)
|
||||
NUL NUL
|
||||
NUL NUL NUL
|
||||
F(VmPTE)
|
||||
F(VmPeak)
|
||||
NUL NUL NUL
|
||||
F(ShdPnd)
|
||||
F(Pid)
|
||||
NUL NUL NUL
|
||||
F(PPid)
|
||||
F(VmLib)
|
||||
NUL NUL NUL
|
||||
F(SigPnd)
|
||||
F(VmLck)
|
||||
NUL NUL NUL
|
||||
F(SigCgt)
|
||||
F(State)
|
||||
NUL NUL NUL
|
||||
F(CapPrm)
|
||||
F(Uid)
|
||||
NUL
|
||||
F(Groups)
|
||||
NUL NUL
|
||||
NUL NUL NUL
|
||||
F(SigIgn)
|
||||
F(SigQ)
|
||||
NUL NUL NUL
|
||||
F(RssShmem)
|
||||
F(Name)
|
||||
NUL NUL NUL
|
||||
F(CapInh)
|
||||
F(VmData)
|
||||
NUL NUL NUL
|
||||
F(FDSize)
|
||||
NUL NUL NUL NUL
|
||||
F(SigBlk)
|
||||
NUL NUL NUL NUL
|
||||
F(CapEff)
|
||||
NUL NUL NUL NUL
|
||||
F(CapBnd)
|
||||
NUL NUL NUL NUL
|
||||
F(VmExe)
|
||||
NUL NUL NUL NUL
|
||||
F(Groups)
|
||||
NUL NUL NUL NUL
|
||||
F(RssAnon)
|
||||
NUL NUL NUL NUL
|
||||
F(RssFile)
|
||||
};
|
||||
|
||||
#undef F
|
||||
@ -248,7 +249,7 @@ ENTER(0x220);
|
||||
// examine a field name (hash and compare)
|
||||
base:
|
||||
if(unlikely(!*S)) break;
|
||||
entry = table[63 & (asso[(int)S[3]] + asso[(int)S[2]] + asso[(int)S[0]])];
|
||||
entry = table[(GPERF_TABLE_SIZE -1) & (asso[(int)S[3]] + asso[(int)S[2]] + asso[(int)S[0]])];
|
||||
colon = strchr(S, ':');
|
||||
if(unlikely(!colon)) break;
|
||||
if(unlikely(colon[1]!='\t')) break;
|
||||
@ -364,6 +365,15 @@ ENTER(0x220);
|
||||
case_VmRSS:
|
||||
P->vm_rss = strtol(S,&S,10);
|
||||
continue;
|
||||
case_RssAnon: // subset of VmRSS, linux-4.5
|
||||
P->vm_rss_anon = strtol(S,&S,10);
|
||||
continue;
|
||||
case_RssFile: // subset of VmRSS, linux-4.5
|
||||
P->vm_rss_file = strtol(S,&S,10);
|
||||
continue;
|
||||
case_RssShmem: // subset of VmRSS, linux-4.5
|
||||
P->vm_rss_shared = strtol(S,&S,10);
|
||||
continue;
|
||||
case_VmSize:
|
||||
P->vm_size = strtol(S,&S,10);
|
||||
continue;
|
||||
@ -439,6 +449,7 @@ ENTER(0x220);
|
||||
|
||||
LEAVE(0x220);
|
||||
}
|
||||
#undef GPERF_TABLE_SIZE
|
||||
|
||||
static void supgrps_from_supgids (proc_t *p) {
|
||||
char *g, *s;
|
||||
|
@ -117,6 +117,9 @@ typedef struct proc_t {
|
||||
vm_size, // status equals 'size' (as kb)
|
||||
vm_lock, // status locked pages (as kb)
|
||||
vm_rss, // status equals 'rss' and/or 'resident' (as kb)
|
||||
vm_rss_anon, // status the 'anonymous' portion of vm_rss (as kb)
|
||||
vm_rss_file, // status the 'file-backed' portion of vm_rss (as kb)
|
||||
vm_rss_shared, // status the 'shared' portion of vm_rss (as kb)
|
||||
vm_data, // status data only size (as kb)
|
||||
vm_stack, // status stack only size (as kb)
|
||||
vm_swap, // status based on linux-2.6.34 "swap ents" (as kb)
|
||||
|
Loading…
Reference in New Issue
Block a user