From fcfa41eb5566df714ae43a08fdbf66626ca8997c Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Tue, 14 Jul 2026 16:52:13 +0200 Subject: [PATCH 1/2] Fix native EH in external shared libs on macOS There is an exception-handling issue on macOS when throwing and catching some standard C++ exceptions in a native C++ lib. The hosts (dotnet, apphost, corerun, nethost) get local copies of typeinfo for several of these exceptions and these copies are not hidden. When an external shared library is loaded, the linker resolves references to those typeinfo instances to the local copies in the host instead of the ones in the libc++. That results in failures matching these exception types in c++ catch. The fix is to disable exporting symbols from these hosts (except for the _get_hostfxr_path from the nethost, which is needed) --- src/coreclr/hosts/corerun/CMakeLists.txt | 8 ++++++++ src/native/corehost/apphost/CMakeLists.txt | 8 ++++++++ src/native/corehost/dotnet/CMakeLists.txt | 8 ++++++++ src/native/corehost/nethost/CMakeLists.txt | 8 ++++++++ 4 files changed, 32 insertions(+) diff --git a/src/coreclr/hosts/corerun/CMakeLists.txt b/src/coreclr/hosts/corerun/CMakeLists.txt index b3baaaa70fc287..9cbd5d2af63848 100644 --- a/src/coreclr/hosts/corerun/CMakeLists.txt +++ b/src/coreclr/hosts/corerun/CMakeLists.txt @@ -11,6 +11,14 @@ endif(CLR_CMAKE_HOST_WIN32) #Required to expose symbols for global symbol discovery. set(CLR_CMAKE_KEEP_NATIVE_SYMBOLS TRUE) +if (CLR_CMAKE_HOST_APPLE) + # Prevent exporting symbols from corerun. This is necessary to avoid a problem with + # local typeinfo for standard C++ EH types like std::bad_alloc, std::out_of_range etc. + # being exposed for binding for external shared libraries and causing mismatch in + # catch type matching. + add_link_options(LINKER:-no_exported_symbols) +endif() + add_executable_clr(corerun corerun.cpp dotenv.cpp diff --git a/src/native/corehost/apphost/CMakeLists.txt b/src/native/corehost/apphost/CMakeLists.txt index 61ff7bc8bd9754..b74a6eb30d8f5c 100644 --- a/src/native/corehost/apphost/CMakeLists.txt +++ b/src/native/corehost/apphost/CMakeLists.txt @@ -1,4 +1,12 @@ # Licensed to the .NET Foundation under one or more agreements. # The .NET Foundation licenses this file to you under the MIT license. +if (CLR_CMAKE_HOST_APPLE) + # Prevent exporting symbols from apphost. This is necessary to avoid a problem with + # local typeinfo for standard C++ EH types like std::bad_alloc, std::out_of_range etc. + # being exposed for binding for external shared libraries and causing mismatch in + # catch type matching. + add_link_options(LINKER:-no_exported_symbols) +endif() + add_subdirectory(standalone) diff --git a/src/native/corehost/dotnet/CMakeLists.txt b/src/native/corehost/dotnet/CMakeLists.txt index 5704c911ac9568..5ff8385ff1af94 100644 --- a/src/native/corehost/dotnet/CMakeLists.txt +++ b/src/native/corehost/dotnet/CMakeLists.txt @@ -1,6 +1,14 @@ # Licensed to the .NET Foundation under one or more agreements. # The .NET Foundation licenses this file to you under the MIT license. +if (CLR_CMAKE_HOST_APPLE) + # Prevent exporting symbols from dotnet. This is necessary to avoid a problem with + # local typeinfo for standard C++ EH types like std::bad_alloc, std::out_of_range etc. + # being exposed for binding for external shared libraries and causing mismatch in + # catch type matching. + add_link_options(LINKER:-no_exported_symbols) +endif() + if(CLR_CMAKE_TARGET_WIN32) list(APPEND SOURCES dotnet.manifest diff --git a/src/native/corehost/nethost/CMakeLists.txt b/src/native/corehost/nethost/CMakeLists.txt index 83c6f4aac8e3ec..1848b108556a42 100644 --- a/src/native/corehost/nethost/CMakeLists.txt +++ b/src/native/corehost/nethost/CMakeLists.txt @@ -1,6 +1,14 @@ # Licensed to the .NET Foundation under one or more agreements. # The .NET Foundation licenses this file to you under the MIT license. +if (CLR_CMAKE_HOST_APPLE) + # Prevent exporting any symbol except _get_hostfxr_path from nethost. This is necessary + # to avoid a problem with local typeinfo for standard C++ EH types like std::bad_alloc, + # std::out_of_range etc. being exposed for binding for external shared libraries and + # causing mismatch in catch type matching. + add_link_options(LINKER:-exported_symbol,_get_hostfxr_path) +endif() + # CMake does not recommend using globbing since it messes with the freshness checks set(SOURCES nethost.cpp From db5d213a388f03d51c18136ba3863f8a186623cb Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Wed, 15 Jul 2026 18:52:26 +0200 Subject: [PATCH 2/2] Add missing export in corerun --- src/coreclr/hosts/corerun/CMakeLists.txt | 10 +++++----- src/native/corehost/nethost/CMakeLists.txt | 8 -------- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/coreclr/hosts/corerun/CMakeLists.txt b/src/coreclr/hosts/corerun/CMakeLists.txt index 9cbd5d2af63848..2cb404a14c951b 100644 --- a/src/coreclr/hosts/corerun/CMakeLists.txt +++ b/src/coreclr/hosts/corerun/CMakeLists.txt @@ -12,11 +12,11 @@ endif(CLR_CMAKE_HOST_WIN32) set(CLR_CMAKE_KEEP_NATIVE_SYMBOLS TRUE) if (CLR_CMAKE_HOST_APPLE) - # Prevent exporting symbols from corerun. This is necessary to avoid a problem with - # local typeinfo for standard C++ EH types like std::bad_alloc, std::out_of_range etc. - # being exposed for binding for external shared libraries and causing mismatch in - # catch type matching. - add_link_options(LINKER:-no_exported_symbols) + # Prevent exporting symbols except for GetCurrentClrDetails from corerun. This is necessary + # to avoid a problem with local typeinfo for standard C++ EH types like std::bad_alloc, + # std::out_of_range etc. being exposed for binding for external shared libraries and causing + # mismatch in catch type matching. + add_link_options(LINKER:-exported_symbol,_GetCurrentClrDetails) endif() add_executable_clr(corerun diff --git a/src/native/corehost/nethost/CMakeLists.txt b/src/native/corehost/nethost/CMakeLists.txt index 1848b108556a42..83c6f4aac8e3ec 100644 --- a/src/native/corehost/nethost/CMakeLists.txt +++ b/src/native/corehost/nethost/CMakeLists.txt @@ -1,14 +1,6 @@ # Licensed to the .NET Foundation under one or more agreements. # The .NET Foundation licenses this file to you under the MIT license. -if (CLR_CMAKE_HOST_APPLE) - # Prevent exporting any symbol except _get_hostfxr_path from nethost. This is necessary - # to avoid a problem with local typeinfo for standard C++ EH types like std::bad_alloc, - # std::out_of_range etc. being exposed for binding for external shared libraries and - # causing mismatch in catch type matching. - add_link_options(LINKER:-exported_symbol,_get_hostfxr_path) -endif() - # CMake does not recommend using globbing since it messes with the freshness checks set(SOURCES nethost.cpp