Files

44 lines
1.8 KiB
Python

import subprocess, os, glob, time, struct
def mem_open(pid): return os.open(f'/proc/{pid}/mem', os.O_RDONLY)
def find_hosts():
hosts=[]
for p in glob.glob('/proc/[0-9]*'):
pid=int(os.path.basename(p))
try:
cmd=open(f'/proc/{pid}/cmdline','rb').read().replace(b'\0',b' ').decode('utf8','replace')
maps=open(f'/proc/{pid}/maps').read()
except Exception: continue
if 'soothe2' in maps and 'reaper' not in cmd:
hosts.append(pid)
return hosts
os.system("pkill -9 -x reaper 2>/dev/null; pkill -9 -f '[y]abridge' 2>/dev/null; sleep 1")
proc=subprocess.Popen(['/usr/bin/reaper','-nosplash','-ignoreerrors','-renderproject','/home/m/soothe-bt/render_long.rpp'],
stdout=open('/dev/null','w'),stderr=subprocess.STDOUT)
t0=time.time(); host=None
while time.time()-t0<60 and not host:
hs=find_hosts(); host=hs[0] if hs else None; time.sleep(0.2)
print('host',host, flush=True)
fd=mem_open(host)
def snap(tag):
out=open('/tmp/snap_%s.bin'%tag,'wb'); idx=open('/tmp/snap_%s.idx'%tag,'wb')
t0=time.time(); nreg=0; nb=0
for line in open(f'/proc/{host}/maps').read().splitlines():
p=line.split(); lo,hi=(int(x,16) for x in p[0].split('-'))
if 'r' not in p[1]: continue
a=lo
while a<hi:
n=min(hi-a,8*1024*1024)
try: d=os.pread(fd,n,a)
except Exception: a+=n; continue
if not d: a+=n; continue
out.write(struct.pack('<QQ',a,len(d))); out.write(d)
idx.write(struct.pack('<QQ',a,len(d)))
nreg+=1; nb+=len(d); a+=n
out.close(); idx.close()
print('snap %s: %d MB %d regs in %.1fs'%(tag,nb/1e6,nreg,time.time()-t0), flush=True)
time.sleep(8); snap('t1')
time.sleep(32); snap('t2')
time.sleep(200)
if proc.poll() is None: proc.kill()
print('done')