From c5d1a92892e871a9feb79630b981836bae795ac4 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Tue, 3 Jan 2023 12:57:47 +0100 Subject: [PATCH 1/4] Run test for autogenerated config in subprocess (#47) Only a single version of a dotnet-core runtime can be loaded at a given time. This off-loads one of our tests to a subprocess (the same pattern would work if we did this for the other test). Could be cleaner, but this will do for now. --- tests/test_common.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/test_common.py b/tests/test_common.py index 1191102..5e5338d 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -57,6 +57,17 @@ def test_coreclr(example_netcore): def test_coreclr_autogenerated_runtimeconfig(example_netstandard): + from multiprocessing import get_context + + p = get_context("spawn").Process( + target=_do_test_coreclr_autogenerated_runtimeconfig, args=(example_netstandard,) + ) + p.start() + p.join() + p.close() + + +def _do_test_coreclr_autogenerated_runtimeconfig(example_netstandard): from clr_loader import get_coreclr coreclr = get_coreclr() From c6b464942fab7a2b2325864c51c75ab897d5f9f8 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Tue, 3 Jan 2023 12:58:41 +0100 Subject: [PATCH 2/4] Adjust CI to only run once on pull requests --- .github/workflows/ci-arm.yml | 8 ++++---- .github/workflows/ci.yml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci-arm.yml b/.github/workflows/ci-arm.yml index 0c308bd..c451f0f 100644 --- a/.github/workflows/ci-arm.yml +++ b/.github/workflows/ci-arm.yml @@ -1,9 +1,9 @@ -# This workflow will install Python dependencies, run tests and lint with a variety of Python versions -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions - name: ARM64 Tests -on: [push, pull_request] +on: + push: + branches: master + pull_request: jobs: build: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 45d1f06..f6f9e75 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,9 +1,9 @@ -# This workflow will install Python dependencies, run tests and lint with a variety of Python versions -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions - name: Python Tests -on: [push, pull_request] +on: + push: + branches: master + pull_request: jobs: build: From 717e797616c6306edff0dd32f8d78679e66d5ca7 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Tue, 3 Jan 2023 06:08:04 -0600 Subject: [PATCH 3/4] Add support for mono_set_dirs (#43) * add support for mono_set_dirs * add set_signal_chaining flag * add tests --- clr_loader/__init__.py | 20 ++++++++++++++++++++ clr_loader/ffi/mono.py | 5 +++++ clr_loader/mono.py | 15 +++++++++++++++ tests/test_common.py | 15 +++++++++++++++ 4 files changed, 55 insertions(+) diff --git a/clr_loader/__init__.py b/clr_loader/__init__.py index d0d8ff2..4b08148 100644 --- a/clr_loader/__init__.py +++ b/clr_loader/__init__.py @@ -30,6 +30,9 @@ def get_mono( sgen: bool = True, debug: bool = False, 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 @@ -48,6 +51,20 @@ def get_mono( Whether to initialise Mono debugging :param jit_options: "Command line options" passed to Mono's ``mono_jit_parse_options`` + :param assembly_dir: + 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 @@ -62,6 +79,9 @@ def get_mono( config_file=_maybe_path(config_file), global_config_file=_maybe_path(global_config_file), 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 ed48cff..c194393 100644 --- a/clr_loader/ffi/mono.py +++ b/clr_loader/ffi/mono.py @@ -39,5 +39,10 @@ MonoObject* mono_runtime_invoke(MonoMethod *method, void *obj, void **params, MonoObject **exc); 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 fb8ab1b..158ddb7 100644 --- a/clr_loader/mono.py +++ b/clr_loader/mono.py @@ -24,6 +24,9 @@ def __init__( jit_options: Optional[Sequence[str]] = None, config_file: Optional[Path] = None, 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] = {} @@ -33,6 +36,9 @@ def __init__( jit_options=jit_options, global_config_file=optional_path_as_string(global_config_file), libmono=libmono, + assembly_dir=assembly_dir, + config_dir=config_dir, + set_signal_chaining=set_signal_chaining, ) if domain is None: @@ -121,11 +127,17 @@ def initialize( jit_options: Optional[Sequence[str]] = None, config_file: Optional[str] = None, global_config_file: Optional[str] = None, + assembly_dir: Optional[str] = None, + config_dir: Optional[str] = None, + set_signal_chaining: bool = False, ) -> str: global _MONO, _ROOT_DOMAIN if _MONO is None: _MONO = load_mono(libmono) + if assembly_dir is not None and config_dir is not None: + _MONO.mono_set_dirs(assembly_dir, config_dir) + # Load in global config (i.e /etc/mono/config) global_encoded = global_config_file or ffi.NULL _MONO.mono_config_parse(global_encoded) @@ -143,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) diff --git a/tests/test_common.py b/tests/test_common.py index 5e5338d..f42020a 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -46,6 +46,21 @@ def test_mono_debug(example_netstandard): run_tests(asm) +def test_mono_signal_chaining(example_netstandard): + from clr_loader import get_mono + + mono = get_mono(set_signal_chaining=True) + asm = mono.get_assembly(example_netstandard / "example.dll") + + run_tests(asm) + +def test_mono_set_dir(example_netstandard): + from clr_loader import get_mono + + mono = get_mono(assembly_dir="/usr/lib", config_dir="/etc") + asm = mono.get_assembly(example_netstandard / "example.dll") + + run_tests(asm) def test_coreclr(example_netcore): from clr_loader import get_coreclr From a56d77cd98c145e65fb58bd510b108ac1614533c Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Tue, 3 Jan 2023 13:08:24 +0100 Subject: [PATCH 4/4] Fix macOS dotnet root discovery (#45) --- clr_loader/util/find.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/clr_loader/util/find.py b/clr_loader/util/find.py index 22ba843..d5d7b89 100644 --- a/clr_loader/util/find.py +++ b/clr_loader/util/find.py @@ -1,5 +1,5 @@ import os -import os.path +import platform import shutil import sys from pathlib import Path @@ -42,7 +42,8 @@ def find_dotnet_root() -> Path: prog_files = Path(prog_files) dotnet_root = prog_files / "dotnet" elif sys.platform == "darwin": - if sys.maxsize > 2**32: # is_64bits + if "ARM64" in os.uname().version and platform.machine() == "x86_64": + # Apple Silicon in Rosetta 2 mode dotnet_root = Path("/usr/local/share/dotnet/x64") else: dotnet_root = Path("/usr/local/share/dotnet")