whisper : catch C++ exceptions in whisper_init_with_params_no_state (#3831)

whisper_model_load() can throw instead of returning false: std::runtime_error
from this file (failed ggml context / no compatible buffer type), or
vk::SystemError / vk::OutOfDeviceMemoryError from the ggml-vulkan backend during
device/buffer allocation.

whisper_init_* are extern "C", so a C++ exception unwinding across that boundary
aborts non-C++ callers (Rust via whisper-rs, Go via cgo) -- on Windows
STATUS_STACK_BUFFER_OVERRUN (0xC0000409) -- even though the function already
returns NULL on failure. Wrap whisper_model_load() in try/catch and route any
throw into the existing NULL-return path.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
danscMax 2026-06-02 14:25:29 +03:00 committed by GitHub
parent e5d4412578
commit 610e664ba7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 15 additions and 1 deletions

View File

@ -3720,7 +3720,21 @@ struct whisper_context * whisper_init_with_params_no_state(struct whisper_model_
whisper_context * ctx = new whisper_context;
ctx->params = params;
if (!whisper_model_load(loader, *ctx)) {
// A C++ exception escaping this extern "C" function aborts non-C++ callers
// (Rust via whisper-rs, Go via cgo, ...). whisper_model_load can throw
// (std::runtime_error here; vk::SystemError from the Vulkan backend during
// device/buffer allocation), so funnel any throw into the existing
// NULL-return failure path instead of letting it cross the C ABI.
bool model_loaded = false;
try {
model_loaded = whisper_model_load(loader, *ctx);
} catch (const std::exception & e) {
WHISPER_LOG_ERROR("%s: exception during model load: %s\n", __func__, e.what());
} catch (...) {
WHISPER_LOG_ERROR("%s: unknown exception during model load\n", __func__);
}
if (!model_loaded) {
loader->close(loader->context);
WHISPER_LOG_ERROR("%s: failed to load model\n", __func__);
delete ctx;