Report correct DLL name when P/Invoke lookup fails (#58863)
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Fri, 10 Sep 2021 16:01:39 +0000 (18:01 +0200)
committerGitHub <noreply@github.com>
Fri, 10 Sep 2021 16:01:39 +0000 (18:01 +0200)
Without this PR when a P/Invoke lookup fails we'll return an exception message that refers to `libcoreclr` instead of the real native library name since we have logic to retry the lookup using libcoreclr. This is very confusing for customers as can be seen in https://github.com/dotnet/runtime/issues/58185.

Co-authored-by: Filip Navara <navara@emclient.com>
src/mono/mono/metadata/native-library.c

index dd67477..f01b9ef 100644 (file)
@@ -951,6 +951,7 @@ lookup_pinvoke_call_impl (MonoMethod *method, MonoLookupPInvokeStatus *status_ou
        const char *new_import = NULL;
        const char *orig_scope = NULL;
        const char *new_scope = NULL;
+       const char *error_scope = NULL;
        char *error_msg = NULL;
        MonoDl *module = NULL;
        gpointer addr = NULL;
@@ -997,6 +998,8 @@ lookup_pinvoke_call_impl (MonoMethod *method, MonoLookupPInvokeStatus *status_ou
        new_import = g_strdup (orig_import);
 #endif
 
+       error_scope = new_scope;
+
        /* If qcalls are disabled, we fall back to the normal pinvoke code for them */
 #ifndef DISABLE_QCALLS
        if (strcmp (new_scope, "QCall") == 0) {
@@ -1051,10 +1054,10 @@ retry_with_libcoreclr:
        if (!module) {
                mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_DLLIMPORT,
                                "DllImport unable to load library '%s'.",
-                               new_scope);
+                               error_scope);
 
                status_out->err_code = LOOKUP_PINVOKE_ERR_NO_LIB;
-               status_out->err_arg = g_strdup (new_scope);
+               status_out->err_arg = g_strdup (error_scope);
                goto exit;
        }
 
@@ -1066,7 +1069,7 @@ retry_with_libcoreclr:
        if (!addr) {
 #ifndef HOST_WIN32
                if (strcmp (new_scope, "__Internal") == 0) {
-                       g_free ((char *)new_scope);
+                       g_assert (error_scope == new_scope);
                        new_scope = g_strdup (MONO_LOADER_LIBRARY_NAME);
                        goto retry_with_libcoreclr;
                }
@@ -1078,6 +1081,9 @@ retry_with_libcoreclr:
        piinfo->addr = addr;
 
 exit:
+       if (error_scope != new_scope) {
+               g_free ((char *)error_scope);
+       }
        g_free ((char *)new_import);
        g_free ((char *)new_scope);
        g_free (error_msg);