wip(nexus): debug crash 0xc000041d khi mở GUI Nexus — lưu trạng thái điều tra (attached() hang; probe exact11 PASS, bridge hang; g_engine hypothesis disproven; chờ phân tích waitscan wait-object)
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
# 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.exe` variant `bridge_exact11` PASS (`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ại `isPlatformTypeSupported=0`, không in `attached=`), 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ọi `instruments.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
|
||||
1. **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).
|
||||
2. 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.
|
||||
3. 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.
|
||||
4. 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.exe` trướ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ên `native_bridge/src/main.cpp` (CRLF! ghi `io.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.wintypes` KHÔ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.
|
||||
Reference in New Issue
Block a user