7c22ae1f02
- 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
106 lines
4.9 KiB
Python
106 lines
4.9 KiB
Python
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))
|