refactor(bridge): split fx bridge, stabilize VST3 host chain, drop old install engines
- remove diagnostic canaries from audio hot path (crackle fix) and stuck C5 note raw-MIDI test (Vst2Instrument::init noteOff) - split native bridge into daw_vst_bridge (VSTi) + fx_vst_bridge (VST FX) - VST3: processData prepare before setActive, zero input buses, accept both .vstpreset and bridge-state blob in RenderJob presets - native_render/vst_engine: bridge-exe discovery + render_fx_chain + /fx-gui - delete old install/ engine binaries (install via sidecar+resources now) - add BUILD_LAYOUT.md, build_selfcheck, tools/ diagnostics
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
import struct, sys
|
||||
|
||||
path = r"C:/Users/locpham/AppData/Local/Temp/sf_dumps/bridge_crash_1696.dmp"
|
||||
data = open(path, "rb").read()
|
||||
|
||||
sig, ver, numstreams, sdir = struct.unpack_from("<IIIIIIQ", data, 0)[:4]
|
||||
print("streams", numstreams, "sdir", hex(sdir))
|
||||
|
||||
streams = {}
|
||||
for i in range(numstreams):
|
||||
stype, datasize, rva = struct.unpack_from("<III", data, sdir + i * 12)
|
||||
streams[stype] = (rva, datasize)
|
||||
|
||||
ThreadList = 3; ModuleList = 4; MemoryList = 5; Exception = 6; SystemInfo = 7
|
||||
|
||||
# Exception stream: ThreadId(4) align(4) MINIDUMP_EXCEPTION(code,flags,rec,addr,nparams,align,params[15]) ThreadContext
|
||||
if Exception in streams:
|
||||
rva, sz = streams[Exception]
|
||||
tid, _ = struct.unpack_from("<II", data, rva)
|
||||
code, flags, rec, exaddr, nparams, _ = struct.unpack_from("<IIQQII", data, rva + 8)
|
||||
print("EXCEPTION tid", tid, "code", hex(code), "exaddr", hex(exaddr), "nparams", nparams)
|
||||
for i in range(nparams):
|
||||
p = struct.unpack_from("<Q", data, rva + 8 + 40 + i * 8)[0]
|
||||
print(" param[%d]" % i, hex(p))
|
||||
|
||||
# Modules
|
||||
mods = []
|
||||
if ModuleList in streams:
|
||||
rva, sz = streams[ModuleList]
|
||||
n = struct.unpack_from("<I", data, rva)[0]
|
||||
pos = rva + 4
|
||||
for i in range(n):
|
||||
base, imgsz, cksum, ts, name_rva = struct.unpack_from("<QIIII", data, pos)
|
||||
nlen = struct.unpack_from("<I", data, name_rva)[0]
|
||||
name = data[name_rva + 4:name_rva + 4 + nlen].decode("utf-16-le", "replace").rstrip("\x00")
|
||||
mods.append((base, imgsz, name))
|
||||
pos += 108 # MINIDUMP_MODULE
|
||||
for base, szz, name in sorted(mods):
|
||||
print("MOD %016x %8x %s" % (base, szz, name))
|
||||
|
||||
# Thread list: ThreadId, SuspendCount, PriorityClass, Priority, Teb, Stack(8), Context(8)
|
||||
thr = {}
|
||||
if ThreadList in streams:
|
||||
rva, sz = streams[ThreadList]
|
||||
n = struct.unpack_from("<I", data, rva)[0]
|
||||
pos = rva + 4
|
||||
for i in range(n):
|
||||
tid2, susp, pric, pri, teb, st_start, st_sz, st_rva, ctx_sz, ctx_rva = struct.unpack_from("<IIIIQQIIII", data, pos)
|
||||
thr[tid2] = (ctx_rva, ctx_sz, st_start, st_rva)
|
||||
pos += 4 * 4 + 8 + 16 + 8
|
||||
for tid2, (ctx_rva, ctx_sz, st_start, st_rva) in sorted(thr.items()):
|
||||
# AMD64 CONTEXT: ContextFlags(4) ... Rax at offset 0x78? Use known layout:
|
||||
# CONTEXT_AMD64: P1Home..P6Home(48) ContextFlags(4) MxCsr(4) SegCs(2)SegDs(2)SegEs(2)SegFs(2)SegGs(2)EFlags(4)Dr0..Dr3(32)Dr6(8)Dr7(8)Rax(8)Rcx(8)Rdx(8)Rbx(8)Rsp(8)Rbp(8)Rsi(8)Rdi(8)R8..R15(64)Rip(8)...
|
||||
if not ctx_rva:
|
||||
continue
|
||||
cf = struct.unpack_from("<I", data, ctx_rva)[0]
|
||||
# offsets (decimal) from CONTEXT_AMD64
|
||||
o_rax = 0x78; o_rcx = 0x80; o_rdx = 0x88; o_rbx = 0x90; o_rsp = 0x98; o_rbp = 0xA0; o_rsi = 0xA8; o_rdi = 0xB0; o_r8 = 0xB8; o_r9 = 0xC0; o_rip = 0xF8
|
||||
rax = struct.unpack_from("<Q", data, ctx_rva + o_rax)[0]
|
||||
rcx = struct.unpack_from("<Q", data, ctx_rva + o_rcx)[0]
|
||||
rdx = struct.unpack_from("<Q", data, ctx_rva + o_rdx)[0]
|
||||
rbx = struct.unpack_from("<Q", data, ctx_rva + o_rbx)[0]
|
||||
rsp = struct.unpack_from("<Q", data, ctx_rva + o_rsp)[0]
|
||||
rbp = struct.unpack_from("<Q", data, ctx_rva + o_rbp)[0]
|
||||
rsi = struct.unpack_from("<Q", data, ctx_rva + o_rsi)[0]
|
||||
rdi = struct.unpack_from("<Q", data, ctx_rva + o_rdi)[0]
|
||||
r8 = struct.unpack_from("<Q", data, ctx_rva + o_r8)[0]
|
||||
r9 = struct.unpack_from("<Q", data, ctx_rva + o_r9)[0]
|
||||
rip = struct.unpack_from("<Q", data, ctx_rva + o_rip)[0]
|
||||
print("THREAD %d RIP %016x RSP %016x RBP %016x RAX %016x RCX %016x RDX %016x R8 %016x R9 %016x" % (tid2, rip, rsp, rbp, rax, rcx, rdx, r8, r9))
|
||||
|
||||
# Memory list for stack walk
|
||||
mems = []
|
||||
if MemoryList in streams:
|
||||
rva, sz = streams[MemoryList]
|
||||
n = struct.unpack_from("<I", data, rva)[0]
|
||||
pos = rva + 4
|
||||
for i in range(n):
|
||||
start, msz, mrva = struct.unpack_from("<QII", data, pos)
|
||||
mems.append((start, msz, mrva))
|
||||
pos += 16
|
||||
|
||||
def mod_for(addr):
|
||||
for base, szz, name in mods:
|
||||
if base <= addr < base + szz:
|
||||
return base, name
|
||||
return None, None
|
||||
|
||||
if Exception in streams and ThreadList in streams:
|
||||
ex_tid = struct.unpack_from("<I", data, streams[Exception][0])[0]
|
||||
if ex_tid in thr:
|
||||
ctx_rva, ctx_sz, st_start, st_rva = thr[ex_tid]
|
||||
rip = struct.unpack_from("<Q", data, ctx_rva + 0xF8)[0]
|
||||
rsp = struct.unpack_from("<Q", data, ctx_rva + 0x98)[0]
|
||||
b, n = mod_for(rip)
|
||||
print("\nCRASH THREAD %d RIP %016x -> %s+%x" % (ex_tid, rip, n.split("\\")[-1] if n else "?", (rip - b) if b else 0))
|
||||
print("stack descriptor start=%016x rva=%x" % (st_start, st_rva))
|
||||
if st_rva:
|
||||
stack = data[st_rva:st_rva + ctx_sz * 2]
|
||||
print("stack bytes available:", len(stack))
|
||||
for j in range(0, min(len(stack), 16384) - 8, 8):
|
||||
val = struct.unpack_from("<Q", stack, j)[0]
|
||||
b2, n2 = mod_for(val)
|
||||
if n2:
|
||||
print(" +%04x %016x -> %s+%x" % (j, val, n2.split("\\")[-1], val - b2))
|
||||
Reference in New Issue
Block a user