re: LIVE N0@44100 = 2048, oversample 4 (two SP instances agree); angle-ramp+Cody-Waite twiddle path confirmed for main FFT; rtone/rtver scripts
This commit is contained in:
+92
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env python3
|
||||
import subprocess, os, glob, sys, time, struct, re
|
||||
|
||||
RPP = sys.argv[1] if len(sys.argv) > 1 else "/home/m/soothe-bt/render_rt.rpp"
|
||||
KEEP = len(sys.argv) > 2 and sys.argv[2] == "keep"
|
||||
|
||||
VPTR = 0x1824abb90 # SpectralProcessor vtbl first entry addr (static). verify at runtime too
|
||||
CTOR = 0x180529610
|
||||
|
||||
proc = subprocess.Popen(
|
||||
['reaper', '-nosplash', '-renderproject', RPP],
|
||||
stdout=open('/tmp/rtdump2.log', 'w'), stderr=subprocess.STDOUT)
|
||||
print('reaper', proc.pid, flush=True)
|
||||
|
||||
host = None
|
||||
deadline = time.time() + 90
|
||||
while time.time() < deadline and not KEEP:
|
||||
found = []
|
||||
for p in glob.glob('/proc/[0-9]*'):
|
||||
try:
|
||||
pid = int(os.path.basename(p))
|
||||
cmd = open(p + '/cmdline', 'rb').read().replace(b'\0', b' ').decode('utf8', 'replace')
|
||||
if 'yabridge-host' not in cmd:
|
||||
continue
|
||||
maps = open(f'/proc/{pid}/maps').read()
|
||||
if 'soothe2' in maps:
|
||||
found.append(pid)
|
||||
except Exception:
|
||||
pass
|
||||
if found:
|
||||
host = found[0]
|
||||
break
|
||||
time.sleep(0.2)
|
||||
print('host', host, flush=True)
|
||||
if not host:
|
||||
if not KEEP:
|
||||
proc.kill()
|
||||
sys.exit('no host')
|
||||
|
||||
# gather ALL readable regions
|
||||
readable = []
|
||||
maps = open(f'/proc/{host}/maps').read()
|
||||
tot = 0
|
||||
for line in maps.splitlines():
|
||||
parts = line.split()
|
||||
lo, hi = (int(x, 16) for x in parts[0].split('-'))
|
||||
if 'r' in parts[1]:
|
||||
readable.append((lo, hi, parts[1]))
|
||||
tot += hi - lo
|
||||
print('readable regions:', len(readable), 'total MB:', tot / 1e6, flush=True)
|
||||
|
||||
mem = os.open(f'/proc/{host}/mem', os.O_RDONLY)
|
||||
pat = {v: struct.pack('<Q', v) for v in (VPTR,)}
|
||||
instances = []
|
||||
scanned = 0
|
||||
for lo, hi, _ in readable:
|
||||
try:
|
||||
d = os.pread(mem, hi - lo, lo)
|
||||
except Exception:
|
||||
continue
|
||||
scanned += len(d)
|
||||
for v, p in pat.items():
|
||||
i = 0
|
||||
while True:
|
||||
i = d.find(p, i)
|
||||
if i < 0:
|
||||
break
|
||||
instances.append((v, lo + i, hi))
|
||||
i += 1
|
||||
os.close(mem)
|
||||
print('scanned bytes MB:', scanned / 1e6, 'instance hits:', len(instances), flush=True)
|
||||
|
||||
if instances:
|
||||
with open('/tmp/instances.txt', 'w') as f:
|
||||
for v, addr, hi in instances:
|
||||
f.write(f'{v:#x} {addr:#x} hi={hi:#x}\n')
|
||||
# dump candidate object memory
|
||||
out = '/tmp/inst_dump.bin'
|
||||
with open(out, 'wb') as f:
|
||||
mem = os.open(f'/proc/{host}/mem', os.O_RDONLY)
|
||||
for v, addr, _ in instances[:16]:
|
||||
base = addr - 0x80
|
||||
f.write(os.pread(mem, 0x2000, base))
|
||||
os.close(mem)
|
||||
print('dumped candidates to', out, flush=True)
|
||||
else:
|
||||
# no instance: dump the module .data section regardless so we can scan for globals
|
||||
print('no instance found', flush=True)
|
||||
|
||||
if not KEEP:
|
||||
proc.kill()
|
||||
print('done', flush=True)
|
||||
Reference in New Issue
Block a user