4.9 KiB
4.9 KiB
Nexus GUI crash 0xc000041d (USER32) — debug state (WIP)
Thời điểm lưu: 2026-08-14, đang chuyển sang máy Linux để tiếp tục.
Hiện tượng
daw_vst_bridge.exe crash 0xc000041d khi mở GUI editor VSTi Nexus (C:\Program Files\Common Files\VST3\Nexus.vst3) rồi chọn instrument khác. Chạy từ install/.
Kết quả đã có
- Probe
gui_probe.exevariantbridge_exact11PASS (RESULT(bridge_exact11): done=1 attached_ok=1, log:openGUI: attached=0= kResultOk), kể cả khi stdout redirect ra file. - NHƯNG bridge thật HANG tại
view->attached()(log dừng tạiisPlatformTypeSupported=0, không inattached=), kể cả SF_ONCE_PROBEWIN=1. Watchdog tick vẫn chạy = đang trong attached().
Đã loại trừ (session 2026-08-14)
- g_engine hypothesis DISPROVEN:
g_engine(main.cpp L545) KHÔNG được dùng trong path SF_ONCE (chỉ dùng ở closeGUI/main-loop). Job SF_ONCE chỉ gọiinstruments.setReloading(y,true)→Vst3Instrument::setReloading(chỉ set bool) +reloadForGUI()(hasAttachedOnce_=false lần đầu → no-op return true). - Diff ChannelWorker vs PumpWorker: giống hệt (chỉ khác tên biến + destructor + comment).
- Diff exact11 vs SF_ONCE: giống hệt về ngữ nghĩa — chỉ khác sampleRate/block, setEditorOpenPredicate (cả hai false), SHM driver thật vs tự tạo (đã loại bằng SF_ONCE_SHM).
- stdout redirect ra file: probe vẫn PASS.
- Binary up-to-date (build 22:09 = main.cpp 22:09).
- CMakeLists: bridge và gui_probe compile CÙNG sources, CÙNG defines (HAVE_VST3SDK=1), cùng libs — không khác.
Stack main thread (stackscan.py v7/v8)
- Main thread chờ vô hạn trong ntdll (R9=0x7ffffffffffffffc timeout ~infinite) qua KERNELBASE+22cd8 gọi từ Nexus attached().
- 3 thread Nexus riêng chờ ntdll+164034; 1 thread (21232) là message pump (win32u+20a4).
- Export resolve thất bại (offset nội bộ không tên): ntdll+5fc6e→hàm tại 0x5fa90, ntdll+3e732→0x3dc60, KERNELBASE+22cd8→hàm tại 0x22ca0.
Bước tiếp theo
- waitscan.py (chạy dở khi lưu): dump RIP mọi thread + NtQueryObject loại/tên handle trong Rcx (wait object) — xem main thread và 3 thread Nexus có CÙNG chờ 1 object (deadlock nội bộ Nexus) hay không. Chạy:
python waitscan.py(cần bridge đang hang). - Nếu waitscan không rõ: disasm KERNELBASE+22ca0 / ntdll+5fa90 xác định hàm chờ (WaitForSingleObjectEx/WaitForMultipleObjectsEx/AlertableWait), hoặc NtQuerySystemInformation wait-chain.
- Khi tìm được trigger: REVERT toàn bộ TEST patch (watchdog, direct attach, no audio, DefWindowProcA, warm-up, pre-window, autogui, exact11, once, once_shm, probewin) — giữ fix chính thức. Đặc biệt:
wc.lpfnWndProc = DefWindowProcA; // TEST ISOLATION- bỏ
WS_VISIBLEở create_native_vst_window - khôi phục VstWindowProc + WS_VISIBLE khi hết test.
- Verify app thật từ
install/(kill SonicForge/daw_vst trước; check%APPDATA%\SonicForgeDAW\logs\bridge.log+ spawn.log, không "bridge stalled 3s"). Deploy exe 5 vị trí: install/, src-tauri/binaries/ (2 tên), src-tauri/target/{debug,release}/.
Cách chạy (Windows)
- Build:
cd native_bridge && cmake --build build --config Release --target daw_vst_bridge --parallel(nhớtaskkill //F //IM daw_vst_bridge.exetrước, LNK1104 nếu zombie). - Probe:
./build/Release/gui_probe.exe "C:\Program Files\Common Files\VST3\Nexus.vst3" <variant> <secs>; exit 127 dù PASS; watchdog tự kill sau secs+10s. - Driver:
python driver_once.py [GATE=VAL...](chờ "SF_ONCE attach=" 90s + "GUI attached" 30s; attach=0 = THÀNH CÔNG).
Scripts trong thư mục này
waitscan.py— dump RIP + wait object mọi thread (đang dở, bước 1 tiếp theo).stackscan.py/stackwalk.py/stack_sample*.py— stack dump.driver_once.py/driver_verify.py/driver_autogui.py/driver_narrow.py— chạy bridge với gate, chờ kết quả.- Patch scripts (workspace tmp-7d619832):
patch_once.py,patch_once_shm.py,patch_exact11_bridge.py,patch_gates.py,patch_autogui.py, ... áp bằng python lênnative_bridge/src/main.cpp(CRLF! ghiio.open(encoding='utf-8', newline='\r\n')).
Learnings kỹ thuật (Windows ctypes)
GetModuleHandleW/windll trả pointer → PHẢI set.restype = ctypes.c_void_p(mặc định c_int → truncate 32-bit → access violation).- Mọi API nhận pointer/handle → set argtypes (GetThreadContext, OpenThread, DuplicateHandle...).
ctypes.wintypesKHÔNG có DWORD64 — dùng ctypes.c_uint64.- CONTEXT x64: SegCs..SegSs là WORD; struct đầy đủ 0x4d0 bytes; GetThreadContext ghi full buffer → dùng raw buffer 0x4d0 + struct.unpack_from offset cố định (rip@0xF8, rsp@0x98, rcx@0x80, rdx@0x88, r8@0xB8, r9@0xC0, ContextFlags@0x30).
- EnumProcessModulesEx: cb = bytes/8 trên x64; module handle có thể NULL → skip.