ASIO close: step-by-step logging + drain before release (Audient crash)
The 'set ASIO driver to none => app dies completely' crash is a NATIVE crash inside the driver's own Stop/Dispose (Audient), which bypasses every managed try/catch and leaves no crash file. Two changes to pin it down and reduce it: - Log each close step (unhook / stop / release / released) so the next crash's log ends right after the native call that died, naming it exactly. - Sleep 60ms after unhooking the callback, before Stop/Dispose, so the native close isn't racing an in-flight ASIO buffer callback (a common crash trigger). Diagnostic + mitigation; the underlying native driver crash needs the Audient hardware to confirm. Gate 37/37. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
d9c78a5956
commit
0c67897448
@@ -209,9 +209,20 @@ internal sealed class AsioCaptureBackend : ICaptureBackend
|
||||
{
|
||||
if (asio is not null)
|
||||
{
|
||||
// Step-by-step logging: closing some drivers (notably Audient) can crash NATIVELY inside their
|
||||
// own Stop/Dispose — a native access violation blows past these try/catch blocks and kills the
|
||||
// process with no managed stack (why the ASIO->none crash leaves no crash file). Logging each
|
||||
// step means the log ends right AFTER the line for whichever native call died, pinpointing it.
|
||||
onDiagnostic?.Invoke("asio close: unhooking callback");
|
||||
try { asio.AudioAvailable -= OnAudioAvailable; } catch { /* ignore */ }
|
||||
try { asio.Stop(); } catch { /* ignore */ }
|
||||
try { asio.Dispose(); } catch { /* ignore */ }
|
||||
// Let any ASIO buffer callback already in flight finish before we stop/release the driver, so
|
||||
// the native close isn't racing a live callback (a common trigger for the crash).
|
||||
System.Threading.Thread.Sleep(60);
|
||||
onDiagnostic?.Invoke("asio close: stopping stream");
|
||||
try { asio.Stop(); } catch (Exception ex) { onDiagnostic?.Invoke($"asio close: stop threw {ex.GetType().Name}: {ex.Message}"); }
|
||||
onDiagnostic?.Invoke("asio close: releasing driver (dispose)");
|
||||
try { asio.Dispose(); } catch (Exception ex) { onDiagnostic?.Invoke($"asio close: dispose threw {ex.GetType().Name}: {ex.Message}"); }
|
||||
onDiagnostic?.Invoke("asio close: driver released cleanly");
|
||||
asio = null;
|
||||
}
|
||||
uptime.Stop();
|
||||
|
||||
Reference in New Issue
Block a user