diff options
author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2022-02-17 17:49:16 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2022-02-17 20:29:50 +0900 |
commit | 992bdfea2d3030c041a33d58221ffdcd91f1a999 (patch) | |
tree | 5c710945a25e5af674bd7b7d4557cd14bcbf29da /dln.c | |
parent | 5952a1f201cfed38277b4fafa0624c1a048edb6d (diff) |
Refine the load error message
Show the linked ruby library name when failed to load extension
built against different ruby library.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/5564
Diffstat (limited to 'dln.c')
-rw-r--r-- | dln.c | 32 |
1 files changed, 27 insertions, 5 deletions
@@ -269,16 +269,31 @@ rb_w32_check_imported(HMODULE ext, HMODULE mine) #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) # 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; } |