G3.2+G3.3: classify hang/crash vs audio stall + SEH per-channel plugin crash isolation (mute channel)
This commit is contained in:
@@ -23,6 +23,7 @@ windows-sys = { version = "0.59", features = [
|
||||
"Win32_Foundation",
|
||||
"Win32_Security",
|
||||
"Win32_System_Memory",
|
||||
"Win32_System_Threading",
|
||||
] }
|
||||
|
||||
[profile.release]
|
||||
|
||||
+33
-2
@@ -95,6 +95,21 @@ fn kill_process_tree(child: &CommandChild) -> bool {
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// G3.2: true if a process with `pid` still exists (OpenProcess + exit code).
|
||||
/// Used to classify a stalled heartbeat: pid alive = HANG, pid gone = CRASH.
|
||||
fn process_alive(pid: u32) -> bool {
|
||||
use windows_sys::Win32::Foundation::STILL_ACTIVE;
|
||||
use windows_sys::Win32::System::Threading::{GetExitCodeProcess, OpenProcess};
|
||||
let handle = unsafe { OpenProcess(windows_sys::Win32::System::Threading::PROCESS_QUERY_LIMITED_INFORMATION, 0, pid) };
|
||||
if handle.is_null() {
|
||||
return false; // not found or no access -> treat as gone
|
||||
}
|
||||
let mut code: u32 = 0;
|
||||
let ok = unsafe { GetExitCodeProcess(handle, &mut code) } != 0;
|
||||
unsafe { windows_sys::Win32::Foundation::CloseHandle(handle) };
|
||||
ok && code == STILL_ACTIVE as u32
|
||||
}
|
||||
|
||||
/// Audio frame pushed to the WebView (bridge SHM -> `bridge-audio` event).
|
||||
#[derive(Clone, serde::Serialize)]
|
||||
struct AudioFrame {
|
||||
@@ -478,8 +493,24 @@ pub fn run() {
|
||||
let log_dir = std::env::var("APPDATA").unwrap_or_else(|_| ".".into());
|
||||
let log_path = std::path::Path::new(&log_dir)
|
||||
.join("SonicForgeDAW").join("logs").join("spawn.log");
|
||||
let mut line = String::from("[tauri] bridge heartbeat stalled 3s — restart attempt #1
|
||||
");
|
||||
// G3.2: phân loại stall — process còn sống = HANG
|
||||
// (heartbeat thread kẹt), pid biến mất = CRASH.
|
||||
let pid = pump_handle
|
||||
.state::<BridgeProcess>()
|
||||
.0
|
||||
.lock()
|
||||
.ok()
|
||||
.and_then(|g| g.as_ref().map(|c| c.pid()));
|
||||
let kind = match pid {
|
||||
Some(p) if process_alive(p) => {
|
||||
format!("HUNG (pid {p} alive, heartbeat stalled)")
|
||||
}
|
||||
Some(p) => format!("CRASHED (pid {p} gone)"),
|
||||
None => "UNKNOWN (no tracked pid)".into(),
|
||||
};
|
||||
let mut line = format!(
|
||||
"[tauri] bridge heartbeat stalled 3s — {kind} — restart attempt #1\n"
|
||||
);
|
||||
// FIX: kill bridge cũ trước — không được để 2 bridge
|
||||
// cùng map SHM (race control queue / double load).
|
||||
kill_bridge(&pump_handle);
|
||||
|
||||
Reference in New Issue
Block a user