diff --git a/src/mono/mono/metadata/native-library.c b/src/mono/mono/metadata/native-library.c
index b2d85270cd3fc..164a3aef132f2 100644
--- a/src/mono/mono/metadata/native-library.c
+++ b/src/mono/mono/metadata/native-library.c
@@ -584,6 +584,40 @@ netcore_probe_for_module_nofail (MonoImage *image, const char *file_name, int fl
return result;
}
+static MonoDl*
+netcore_lookup_self_native_handle (void)
+{
+ ERROR_DECL (load_error);
+ if (!internal_module)
+ internal_module = mono_dl_open_self (load_error);
+
+ if (!internal_module)
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT, "DllImport error loading library '__Internal': '%s'.", mono_error_get_message_without_fields (load_error));
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DLLIMPORT, "Native library found via __Internal.");
+ mono_error_cleanup (load_error);
+
+ return internal_module;
+}
+
+static MonoDl* native_handle_lookup_wrapper (gpointer handle)
+{
+ MonoDl *result = NULL;
+
+ if (!internal_module)
+ netcore_lookup_self_native_handle ();
+
+ if (internal_module->handle == handle) {
+ result = internal_module;
+ } else {
+ native_library_lock ();
+ result = netcore_handle_lookup (handle);
+ native_library_unlock ();
+ }
+
+ return result;
+}
+
static MonoDl *
netcore_resolve_with_dll_import_resolver (MonoAssemblyLoadContext *alc, MonoAssembly *assembly, const char *scope, guint32 flags, MonoError *error)
{
@@ -631,9 +665,7 @@ netcore_resolve_with_dll_import_resolver (MonoAssemblyLoadContext *alc, MonoAsse
mono_runtime_invoke_checked (resolve, NULL, args, error);
goto_if_nok (error, leave);
- native_library_lock ();
- result = netcore_handle_lookup (lib);
- native_library_unlock ();
+ result = native_handle_lookup_wrapper (lib);
leave:
HANDLE_FUNCTION_RETURN_VAL (result);
@@ -688,9 +720,7 @@ netcore_resolve_with_load (MonoAssemblyLoadContext *alc, const char *scope, Mono
mono_runtime_invoke_checked (resolve, NULL, args, error);
goto_if_nok (error, leave);
- native_library_lock ();
- result = netcore_handle_lookup (lib);
- native_library_unlock ();
+ result = native_handle_lookup_wrapper (lib);
leave:
HANDLE_FUNCTION_RETURN_VAL (result);
@@ -755,9 +785,7 @@ netcore_resolve_with_resolving_event (MonoAssemblyLoadContext *alc, MonoAssembly
mono_runtime_invoke_checked (resolve, NULL, args, error);
goto_if_nok (error, leave);
- native_library_lock ();
- result = netcore_handle_lookup (lib);
- native_library_unlock ();
+ result = native_handle_lookup_wrapper (lib);
leave:
HANDLE_FUNCTION_RETURN_VAL (result);
@@ -802,22 +830,6 @@ netcore_check_alc_cache (MonoAssemblyLoadContext *alc, const char *scope)
return result;
}
-static MonoDl*
-netcore_lookup_self_native_handle (void)
-{
- ERROR_DECL (load_error);
- if (!internal_module)
- internal_module = mono_dl_open_self (load_error);
-
- if (!internal_module)
- mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT, "DllImport error loading library '__Internal': '%s'.", mono_error_get_message_without_fields (load_error));
-
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DLLIMPORT, "Native library found via __Internal.");
- mono_error_cleanup (load_error);
-
- return internal_module;
-}
-
static MonoDl *
netcore_lookup_native_library (MonoAssemblyLoadContext *alc, MonoImage *image, const char *scope, guint32 flags)
{
diff --git a/src/mono/mono/utils/mono-dl.c b/src/mono/mono/utils/mono-dl.c
index 512ce7205e606..c4e5d5eafad24 100644
--- a/src/mono/mono/utils/mono-dl.c
+++ b/src/mono/mono/utils/mono-dl.c
@@ -176,8 +176,9 @@ fix_libc_name (const char *name)
* mono_dl_open_self:
* \param error pointer to MonoError
*
- * Returns a handle to the main program, on android x86 it's not possible to
- * call dl_open(null), it returns a null handle, so this function returns RTLD_DEFAULT
+ * Returns a handle to the main program, on Android it's not possible to
+ * call dl_open(null) with RTLD_LAZY, it returns a null handle, so this
+ * function uses RTLD_NOW.
* handle in this platform.
* \p error points to MonoError where an error will be stored in
* case of failure. The error needs to be cleared when done using it, \c mono_error_cleanup.
@@ -195,7 +196,7 @@ mono_dl_open_self (MonoError *error)
return NULL;
}
mono_refcount_init (module, NULL);
- module->handle = RTLD_DEFAULT;
+ module->handle = dlopen(NULL, RTLD_NOW);
module->dl_fallback = NULL;
module->full_name = NULL;
return module;
diff --git a/src/native/libs/System.Native/pal_dynamicload.c b/src/native/libs/System.Native/pal_dynamicload.c
index 6aaf70f50fcdd..76f9c56678af5 100644
--- a/src/native/libs/System.Native/pal_dynamicload.c
+++ b/src/native/libs/System.Native/pal_dynamicload.c
@@ -56,12 +56,6 @@ void SystemNative_FreeLibrary(void* handle)
dlclose(handle);
}
-#ifdef TARGET_ANDROID
-void* SystemNative_GetDefaultSearchOrderPseudoHandle(void)
-{
- return (void*)RTLD_DEFAULT;
-}
-#else
static void* volatile g_defaultSearchOrderPseudoHandle = NULL;
void* SystemNative_GetDefaultSearchOrderPseudoHandle(void)
{
@@ -69,11 +63,16 @@ void* SystemNative_GetDefaultSearchOrderPseudoHandle(void)
void* defaultSearchOrderPseudoHandle = (void*)g_defaultSearchOrderPseudoHandle;
if (defaultSearchOrderPseudoHandle == NULL)
{
+#ifdef TARGET_ANDROID
+ int flag = RTLD_NOW;
+#else
+ int flag = RTLD_LAZY;
+#endif
+
// Assign back to the static as well as the local here.
// We don't need to check for a race between two threads as the value returned by
// dlopen here will always be the same in a given environment.
- g_defaultSearchOrderPseudoHandle = defaultSearchOrderPseudoHandle = dlopen(NULL, RTLD_LAZY);
+ g_defaultSearchOrderPseudoHandle = defaultSearchOrderPseudoHandle = dlopen(NULL, flag);
}
return defaultSearchOrderPseudoHandle;
}
-#endif
diff --git a/src/tests/Interop/NativeLibrary/MainProgramHandle/MainProgramHandleTests.cs b/src/tests/Interop/NativeLibrary/MainProgramHandle/MainProgramHandleTests.cs
new file mode 100644
index 0000000000000..c526c2a8d2a0a
--- /dev/null
+++ b/src/tests/Interop/NativeLibrary/MainProgramHandle/MainProgramHandleTests.cs
@@ -0,0 +1,46 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+using Xunit;
+
+public static class MainProgramHandleTests
+{
+ private static IntPtr s_handle;
+
+ static MainProgramHandleTests() => NativeLibrary.SetDllImportResolver(typeof(MainProgramHandleTests).Assembly,
+ (string libraryName, Assembly asm, DllImportSearchPath? dllImportSearchPath) =>
+ {
+ if (libraryName == "Self")
+ {
+ s_handle = NativeLibrary.GetMainProgramHandle();
+ Assert.NotEqual(IntPtr.Zero, s_handle);
+ return s_handle;
+ }
+
+ return IntPtr.Zero;
+ });
+
+ public static int Main()
+ {
+ try
+ {
+ free(s_handle);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine($"Test Failure: {e}");
+ return 101;
+ }
+
+ return 100;
+ }
+
+ [DllImport("Self")]
+ private static extern void free(IntPtr arg);
+}
diff --git a/src/tests/Interop/NativeLibrary/MainProgramHandle/MainProgramHandleTests.csproj b/src/tests/Interop/NativeLibrary/MainProgramHandle/MainProgramHandleTests.csproj
new file mode 100644
index 0000000000000..1ce6225d7853c
--- /dev/null
+++ b/src/tests/Interop/NativeLibrary/MainProgramHandle/MainProgramHandleTests.csproj
@@ -0,0 +1,13 @@
+
+
+ Exe
+ true
+ true
+
+
+
+
+
+
+
+
diff --git a/src/tests/issues.targets b/src/tests/issues.targets
index 6eaf2dcf8fb3c..3b6ef72bff560 100644
--- a/src/tests/issues.targets
+++ b/src/tests/issues.targets
@@ -2690,6 +2690,9 @@
needs triage
+
+ needs triage
+
https://github.com/dotnet/runtime/issues/47624