[前][次][番号順一覧][スレッド一覧]

ruby-changes:71200

From: Nobuyoshi <ko1@a...>
Date: Thu, 17 Feb 2022 21:53:18 +0900 (JST)
Subject: [ruby-changes:71200] 992bdfea2d (master): Refine the load error message

https://git.ruby-lang.org/ruby.git/commit/?id=992bdfea2d

From 992bdfea2d3030c041a33d58221ffdcd91f1a999 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Thu, 17 Feb 2022 17:49:16 +0900
Subject: Refine the load error message

Show the linked ruby library name when failed to load extension
built against different ruby library.
---
 dln.c | 32 +++++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git a/dln.c b/dln.c
index 5c1e6f8c02..902f187283 100644
--- a/dln.c
+++ b/dln.c
@@ -269,16 +269,31 @@ rb_w32_check_imported(HMODULE ext, HMODULE mine) https://github.com/ruby/ruby/blob/trunk/dln.c#L269
 #ifdef USE_DLN_DLOPEN
 # include "ruby/internal/stdbool.h"
 # include "internal/warnings.h"
+static bool
+dln_incompatible_func(void *handle, const char *funcname, void *const fp, const char **libname)
+{
+    Dl_info dli;
+    void *ex = dlsym(handle, funcname);
+    if (!ex) return false;
+    if (ex == fp) return false;
+    if (dladdr(ex, &dli)) {
+	*libname = dli.dli_fname;
+    }
+    return true;
+}
+
 COMPILER_WARNING_PUSH
 #if defined(__clang__) || GCC_VERSION_SINCE(4, 2, 0)
 COMPILER_WARNING_IGNORED(-Wpedantic)
 #endif
 static bool
-dln_incompatible_library_p(void *handle)
+dln_incompatible_library_p(void *handle, const char **libname)
 {
-    void *ex = dlsym(handle, EXTERNAL_PREFIX"ruby_xmalloc");
-    void *const fp = (void *)ruby_xmalloc;
-    return ex && ex != fp;
+#define check_func(func) \
+    if (dln_incompatible_func(handle, EXTERNAL_PREFIX #func, (void *)&func, libname)) \
+	return true
+    check_func(ruby_xmalloc);
+    return false;
 }
 COMPILER_WARNING_POP
 #endif
@@ -356,13 +371,20 @@ dln_open(const char *file) https://github.com/ruby/ruby/blob/trunk/dln.c#L371
 
 # if defined(RUBY_EXPORT)
     {
-	if (dln_incompatible_library_p(handle)) {
+	const char *libruby_name = NULL;
+	if (dln_incompatible_library_p(handle, &libruby_name)) {
 	    if (dln_disable_dlclose()) {
 		/* dlclose() segfaults */
+		if (libruby_name) {
+		    dln_fatalerror("linked to incompatible %s - %s", libruby_name, file);
+		}
 		dln_fatalerror("%s - %s", incompatible, file);
 	    }
 	    else {
 		dlclose(handle);
+		if (libruby_name) {
+		    dln_loaderror("linked to incompatible %s - %s", libruby_name, file);
+		}
 		error = incompatible;
 		goto failed;
 	    }
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]