feat(ffi): unwind safety: shield FFI entrypoints with panic guard (#546)

This PR implements widely accepted Rust programming practices for
dealing with panics across ABI (programming language) boundaries.

- Add panic_guard.rs to wrap FFI calls and prevent panic across FFI/ABI boundary (undefined behavior).
- Capture per-thread backtraces via a temporary panic hook
- After a panic, subsequent invocations are poisoned.
- Integrate with_unwind_guard across the engine, schema registry, and target registry exportis

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
This commit is contained in:
Anand Krishnamoorthi
2026-01-20 21:50:10 -06:00
committed by GitHub
parent 9426b2ec02
commit 80686d6ed1
21 changed files with 1008 additions and 501 deletions

View File

@@ -217,6 +217,20 @@ namespace Regorus.Internal
[DllImport(LibraryName, EntryPoint = "regorus_engine_compile_with_entrypoint", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern RegorusResult regorus_engine_compile_with_entrypoint(RegorusEngine* engine, byte* rule);
#if REGORUS_FFI_TEST_HOOKS
/// <summary>
/// Trigger a panic inside the engine for testing purposes.
/// </summary>
[DllImport(LibraryName, EntryPoint = "regorus_engine_test_trigger_panic", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern RegorusResult regorus_engine_test_trigger_panic();
/// <summary>
/// Reset the engine poison flag for testing.
/// </summary>
[DllImport(LibraryName, EntryPoint = "regorus_engine_test_reset_poison", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern void regorus_engine_test_reset_poison();
#endif
#endregion
#region Compilation Methods
@@ -472,6 +486,14 @@ namespace Regorus.Internal
/// Invalid policy content.
/// </summary>
InvalidPolicy,
/// <summary>
/// The engine panicked and cannot be reused until reset.
/// </summary>
Panic,
/// <summary>
/// The engine remains poisoned because a previous panic was detected.
/// </summary>
Poisoned,
}
/// <summary>