diff --git a/clr_loader/__init__.py b/clr_loader/__init__.py index 7927821..4b08148 100644 --- a/clr_loader/__init__.py +++ b/clr_loader/__init__.py @@ -32,6 +32,7 @@ def get_mono( jit_options: Optional[Sequence[str]] = None, assembly_dir: Optional[str] = None, config_dir: Optional[str] = None, + set_signal_chaining: bool = False ) -> Runtime: """Get a Mono runtime instance @@ -54,6 +55,16 @@ def get_mono( The base directory for assemblies, passed to ``mono_set_dirs`` :param config_dir: The base directory for configuration files, passed to ``mono_set_dirs`` + :param set_signal_chaining: + Whether to enable signal chaining, passed to ``mono_set_signal_chaining``. + If it is enabled, the runtime saves the original signal handlers before + installing its own, and calls the original ones in the following cases: + - SIGSEGV/SIGABRT while executing native code + - SIGPROF + - SIGFPE + - SIGQUIT + - SIGUSR2 + This currently only works on POSIX platforms """ from .mono import Mono @@ -70,6 +81,7 @@ def get_mono( libmono=libmono, assembly_dir=assembly_dir, config_dir=config_dir, + set_signal_chaining=set_signal_chaining, ) return impl diff --git a/clr_loader/ffi/mono.py b/clr_loader/ffi/mono.py index 4898f21..c194393 100644 --- a/clr_loader/ffi/mono.py +++ b/clr_loader/ffi/mono.py @@ -41,5 +41,8 @@ void* mono_object_unbox(MonoObject *object); void mono_set_dirs(const char *assembly_dir, const char* config_dir); + +void mono_set_signal_chaining(bool chain_signals); + """ ) diff --git a/clr_loader/mono.py b/clr_loader/mono.py index 356f511..158ddb7 100644 --- a/clr_loader/mono.py +++ b/clr_loader/mono.py @@ -26,6 +26,7 @@ def __init__( global_config_file: Optional[Path] = None, assembly_dir: Optional[str] = None, config_dir: Optional[str] = None, + set_signal_chaining: bool = False, ): self._assemblies: Dict[Path, Any] = {} @@ -37,6 +38,7 @@ def __init__( libmono=libmono, assembly_dir=assembly_dir, config_dir=config_dir, + set_signal_chaining=set_signal_chaining, ) if domain is None: @@ -126,7 +128,8 @@ def initialize( config_file: Optional[str] = None, global_config_file: Optional[str] = None, assembly_dir: Optional[str] = None, - config_dir: Optional[str] = None + config_dir: Optional[str] = None, + set_signal_chaining: bool = False, ) -> str: global _MONO, _ROOT_DOMAIN if _MONO is None: @@ -152,6 +155,9 @@ def initialize( else: options = [] + if set_signal_chaining: + _MONO.mono_set_signal_chaining(True) + if debug: _MONO.mono_debug_init(_MONO.MONO_DEBUG_FORMAT_MONO)