171 lines
5.0 KiB
Python
171 lines
5.0 KiB
Python
|
|
#!/bin/env python
|
||
|
|
|
||
|
|
# Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
|
||
|
|
# Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
|
||
|
|
# perms
|
||
|
|
# r = read
|
||
|
|
# w = write
|
||
|
|
# x = execute
|
||
|
|
# s = shared
|
||
|
|
# p = private (copy on write)
|
||
|
|
|
||
|
|
import sys, os, pwd, re, json
|
||
|
|
|
||
|
|
re_mapheader = re.compile('[0-9a-f]+-[0-9a-f]+', re.IGNORECASE)
|
||
|
|
|
||
|
|
def readFileLines(name):
|
||
|
|
with file(name) as f:
|
||
|
|
s = f.readlines()
|
||
|
|
return s
|
||
|
|
|
||
|
|
def readFile(name):
|
||
|
|
x=readFileLines(name)
|
||
|
|
if x:
|
||
|
|
return x[0]
|
||
|
|
else:
|
||
|
|
return None
|
||
|
|
|
||
|
|
def getProcRec(pid):
|
||
|
|
try:
|
||
|
|
mr={}
|
||
|
|
mr['pid'] = pid
|
||
|
|
mr['comm'] = readFile('/proc/' + pid + '/comm')
|
||
|
|
mr['cmdline'] = readFile('/proc/' + pid + '/cmdline')
|
||
|
|
mr['username'] = pwd.getpwuid(os.stat('/proc/' + pid).st_uid).pw_name
|
||
|
|
|
||
|
|
except IOError as e:
|
||
|
|
print "Process gone"
|
||
|
|
except Exception as e:
|
||
|
|
print "error", e
|
||
|
|
raise
|
||
|
|
return mr
|
||
|
|
|
||
|
|
def getProcMemData(pid):
|
||
|
|
memseg={}
|
||
|
|
memdetail={}
|
||
|
|
allmemseg={}
|
||
|
|
allmemdetail={}
|
||
|
|
|
||
|
|
try:
|
||
|
|
for l in readFileLines('/proc/' + pid + '/smaps'):
|
||
|
|
if re_mapheader.match(l):
|
||
|
|
memseg['baddr_hex'] = l.split()[0].split('-')[0]
|
||
|
|
memseg['eaddr_hex'] = l.split()[0].split('-')[1]
|
||
|
|
memseg['perms'] = l.split()[1]
|
||
|
|
memseg['offset'] = l.split()[2]
|
||
|
|
memseg['dev'] = l.split()[3]
|
||
|
|
memseg['inode'] = l.split()[4]
|
||
|
|
if len(l.split()) >= 6:
|
||
|
|
s = l.split()[5]
|
||
|
|
if s.startswith('/dev/shm'):
|
||
|
|
s = '/dev/shm'
|
||
|
|
#re.sub('', '', s)
|
||
|
|
#print "s =", s
|
||
|
|
memseg['name'] = s
|
||
|
|
else:
|
||
|
|
memseg['name'] = '[anon]'
|
||
|
|
memseg['baddr'] = int(memseg['baddr_hex'], 16)
|
||
|
|
memseg['eaddr'] = int(memseg['eaddr_hex'], 16)
|
||
|
|
memseg['size'] = memseg['eaddr'] - memseg['baddr']
|
||
|
|
|
||
|
|
allmemseg[memseg['name']] = memseg
|
||
|
|
else:
|
||
|
|
# smaps format example:
|
||
|
|
# Size: 136 kB
|
||
|
|
# Rss: 40 kB ...
|
||
|
|
memdetail[l.split()[0].replace(':','')] = memdetail.get(l.split()[0].replace(':',''), 0) + int(l.split()[1])
|
||
|
|
|
||
|
|
allmemdetail[memseg['name']] = memdetail
|
||
|
|
|
||
|
|
return allmemseg, allmemdetail
|
||
|
|
|
||
|
|
except IOError as e:
|
||
|
|
print "Process gone"
|
||
|
|
except Exception as e:
|
||
|
|
print "error", e
|
||
|
|
raise
|
||
|
|
|
||
|
|
def getProcMemDataSum(pidlist):
|
||
|
|
memsum = {}
|
||
|
|
for p in pidlist:
|
||
|
|
procrec = getProcRec(p)
|
||
|
|
#print "\n============ PID: %d %s" % ( int(procrec['pid']), procrec['cmdline'].replace('\x00','') )
|
||
|
|
memseg, memdata = getProcMemData(p)
|
||
|
|
#print memseg
|
||
|
|
for ms in memseg:
|
||
|
|
memsum[ms] = memdata[ms]
|
||
|
|
#for i in memdata[ms]:
|
||
|
|
# #print "%-25s %10d kB %s" % ( i, memdata[ms][i], ms )
|
||
|
|
# memsum[(ms,i)] = memsum.get((ms,i), 0) + memdata[ms][i]
|
||
|
|
|
||
|
|
return memsum
|
||
|
|
|
||
|
|
def main(argv):
|
||
|
|
memdatasum = getProcMemDataSum(argv)
|
||
|
|
#print memdatasum
|
||
|
|
#print json.dumps(memdatasum, indent=4)
|
||
|
|
print "%10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %s" % (
|
||
|
|
'VSize'
|
||
|
|
, 'PTE'
|
||
|
|
, 'Locked'
|
||
|
|
, 'MMUPages'
|
||
|
|
, 'Priv_Clean'
|
||
|
|
, 'Priv_Dirty'
|
||
|
|
, 'Pss'
|
||
|
|
, 'Referenced'
|
||
|
|
, 'Rss'
|
||
|
|
, 'Shr_Clean'
|
||
|
|
, 'Shr_Dirty'
|
||
|
|
, 'Swap'
|
||
|
|
, ' Segment_Name'
|
||
|
|
)
|
||
|
|
print "%10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %s" % (
|
||
|
|
'----------'
|
||
|
|
, '----------'
|
||
|
|
, '----------'
|
||
|
|
, '----------'
|
||
|
|
, '----------'
|
||
|
|
, '----------'
|
||
|
|
, '----------'
|
||
|
|
, '----------'
|
||
|
|
, '----------'
|
||
|
|
, '----------'
|
||
|
|
, '----------'
|
||
|
|
, '----------'
|
||
|
|
, ' ----------------------------------------------------------------------'
|
||
|
|
)
|
||
|
|
for mseg in memdatasum:
|
||
|
|
m = memdatasum[mseg]
|
||
|
|
print "%10d %10d %10d %10d %10d %10d %10d %10d %10d %10d %10d %10d %s" % (
|
||
|
|
m.get('Size', 0)
|
||
|
|
, m.get('KernelPageSize', 0)
|
||
|
|
, m.get('Locked', 0)
|
||
|
|
, m.get('MMUPageSize', 0)
|
||
|
|
, m.get('Private_Clean', 0)
|
||
|
|
, m.get('Private_Dirty', 0)
|
||
|
|
, m.get('Pss', 0)
|
||
|
|
, m.get('Referenced', 0)
|
||
|
|
, m.get('Rss', 0)
|
||
|
|
, m.get('Shared_Clean', 0)
|
||
|
|
, m.get('Shared_Dirty', 0)
|
||
|
|
, m.get('Swap', 0)
|
||
|
|
, mseg
|
||
|
|
)
|
||
|
|
|
||
|
|
#for a in argv:
|
||
|
|
# procrec = getProcRec(a)
|
||
|
|
# print "\n============ PID: %d %s" % ( int(procrec['pid']), procrec['cmdline'].replace('\x00','') )
|
||
|
|
# memseg, memdata = getProcMemData(a)
|
||
|
|
# #for i in sorted(memdata, key=memdata.get, reverse=False):
|
||
|
|
# for i in sorted(memdata, reverse=False):
|
||
|
|
# print "%-25s %10d kB" % ( i, memdata[i] )
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
main(sys.argv[1:])
|
||
|
|
|