Get error from dln_open when USE_SHARED_GC
Before, if dln_open failed to open RUBY_GC_LIBRARY_PATH, it would segfault because it would try to raise an error, which cannot happen because the GC has not been initialized yet. This commit changes dln_open to return the error that occurred so the caller can handle the error.
This commit is contained in:
parent
81433fd0f5
commit
b9109b270d
29
dln.c
29
dln.c
@ -340,10 +340,9 @@ dln_disable_dlclose(void)
|
|||||||
|
|
||||||
#if defined(_WIN32) || defined(USE_DLN_DLOPEN)
|
#if defined(_WIN32) || defined(USE_DLN_DLOPEN)
|
||||||
void *
|
void *
|
||||||
dln_open(const char *file)
|
dln_open(const char *file, const char **error)
|
||||||
{
|
{
|
||||||
static const char incompatible[] = "incompatible library version";
|
static const char incompatible[] = "incompatible library version";
|
||||||
const char *error = NULL;
|
|
||||||
void *handle;
|
void *handle;
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
@ -360,15 +359,15 @@ dln_open(const char *file)
|
|||||||
free(winfile);
|
free(winfile);
|
||||||
|
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
error = dln_strerror();
|
*error = dln_strerror();
|
||||||
goto failed;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
# if defined(RUBY_EXPORT)
|
# if defined(RUBY_EXPORT)
|
||||||
if (!rb_w32_check_imported(handle, rb_libruby_handle())) {
|
if (!rb_w32_check_imported(handle, rb_libruby_handle())) {
|
||||||
FreeLibrary(handle);
|
FreeLibrary(handle);
|
||||||
error = incompatible;
|
*error = incompatible;
|
||||||
goto failed;
|
return NULL;
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
@ -387,8 +386,8 @@ dln_open(const char *file)
|
|||||||
/* Load file */
|
/* Load file */
|
||||||
handle = dlopen(file, RTLD_LAZY|RTLD_GLOBAL);
|
handle = dlopen(file, RTLD_LAZY|RTLD_GLOBAL);
|
||||||
if (handle == NULL) {
|
if (handle == NULL) {
|
||||||
error = dln_strerror();
|
*error = dln_strerror();
|
||||||
goto failed;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
# if defined(RUBY_EXPORT)
|
# if defined(RUBY_EXPORT)
|
||||||
@ -413,8 +412,8 @@ dln_open(const char *file)
|
|||||||
if (libruby_name) {
|
if (libruby_name) {
|
||||||
dln_loaderror("linked to incompatible %s - %s", libruby_name, file);
|
dln_loaderror("linked to incompatible %s - %s", libruby_name, file);
|
||||||
}
|
}
|
||||||
error = incompatible;
|
*error = incompatible;
|
||||||
goto failed;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -422,9 +421,6 @@ dln_open(const char *file)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
|
|
||||||
failed:
|
|
||||||
dln_loaderror("%s - %s", error, file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
@ -501,7 +497,12 @@ void *
|
|||||||
dln_load(const char *file)
|
dln_load(const char *file)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32) || defined(USE_DLN_DLOPEN)
|
#if defined(_WIN32) || defined(USE_DLN_DLOPEN)
|
||||||
void *handle = dln_open(file);
|
const char *error = NULL;
|
||||||
|
void *handle = dln_open(file, &error);
|
||||||
|
|
||||||
|
if (handle == NULL) {
|
||||||
|
dln_loaderror("%s - %s", error, file);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef RUBY_DLN_CHECK_ABI
|
#ifdef RUBY_DLN_CHECK_ABI
|
||||||
typedef unsigned long long abi_version_number;
|
typedef unsigned long long abi_version_number;
|
||||||
|
2
dln.h
2
dln.h
@ -25,7 +25,7 @@ RUBY_SYMBOL_EXPORT_BEGIN
|
|||||||
char *dln_find_exe_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL);
|
char *dln_find_exe_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL);
|
||||||
char *dln_find_file_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL);
|
char *dln_find_file_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL);
|
||||||
void *dln_load(const char*);
|
void *dln_load(const char*);
|
||||||
void *dln_open(const char *file);
|
void *dln_open(const char *file, const char **error);
|
||||||
void *dln_symbol(void*,const char*);
|
void *dln_symbol(void*,const char*);
|
||||||
|
|
||||||
RUBY_SYMBOL_EXPORT_END
|
RUBY_SYMBOL_EXPORT_END
|
||||||
|
4
dmydln.c
4
dmydln.c
@ -21,9 +21,9 @@ dln_symbol(void *handle, const char *symbol)
|
|||||||
UNREACHABLE_RETURN(NULL);
|
UNREACHABLE_RETURN(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
NORETURN(void *dln_open(const char*));
|
NORETURN(void *dln_open(const char *library, const char **error));
|
||||||
void*
|
void*
|
||||||
dln_open(const char *library)
|
dln_open(const char *library, const char **error)
|
||||||
{
|
{
|
||||||
rb_loaderror("this executable file can't load extension libraries");
|
rb_loaderror("this executable file can't load extension libraries");
|
||||||
|
|
||||||
|
13
gc.c
13
gc.c
@ -1900,20 +1900,15 @@ ruby_external_gc_init()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *h = dln_open(gc_so_path);
|
const char *error = NULL;
|
||||||
|
void *h = dln_open(gc_so_path, &error);
|
||||||
if (!h) {
|
if (!h) {
|
||||||
rb_bug(
|
rb_bug("ruby_external_gc_init: Shared library %s cannot be opened (%s)", gc_so_path, error);
|
||||||
"ruby_external_gc_init: Shared library %s cannot be opened.",
|
|
||||||
gc_so_path
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *gc_init_func = dln_symbol(h, "Init_GC");
|
void *gc_init_func = dln_symbol(h, "Init_GC");
|
||||||
if (!gc_init_func) {
|
if (!gc_init_func) {
|
||||||
rb_bug(
|
rb_bug("ruby_external_gc_init: Init_GC func not exported by library %s", gc_so_path);
|
||||||
"ruby_external_gc_init: Init_GC func not exported by library %s",
|
|
||||||
gc_so_path
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
map->init = gc_init_func;
|
map->init = gc_init_func;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user