|
Last change
on this file since 1f65aee was
1f65aee,
checked in by Benjamin Kaduk <kaduk@mit.edu>, 14 months ago
|
|
Properly check for dlsym() errors
In closures.c we dlopen() the main process address space so we can get
references to gvalue_from_sv, sv_from_gvalue, and perl_closure_new, but
we only check for errors by seeing if dlerror() returns a non-NULL
pointer (string). This is not correct, since we are only supposed to
inspect dlerror()'s contents if one of a certain list of functions has
returned an error (dlerror() returns information about the latest such
error).
This causes problems on FreeBSD, where the NSS implementation in libc
performs a dlsym() lookup of a "_nss_cache_cycle_protection_function"
symbls, which fails in all processes other than nscd. The FreeBSD libc
does not subsequently call dlerror() to clear the error string and so
it remains cached until we inspect it, and we erroneously treat this
cached value as indicating an error in our dlsym() usage, which trickles
up and becomes a fatal error at startup.
Fix the issue by only calling dlerror() if we experienced an error
return from dlsym() or dlclose(), clearing res to NULL in the success
case.
|
-
Property mode set to
100644
|
|
File size:
928 bytes
|
| Line | |
|---|
| 1 | #define OWL_PERL |
|---|
| 2 | #include "owl.h" |
|---|
| 3 | #include <dlfcn.h> |
|---|
| 4 | #include <gperl.h> |
|---|
| 5 | #include <gperl_marshal.h> |
|---|
| 6 | |
|---|
| 7 | gboolean (*gvalue_from_sv) (GValue * value, SV * sv) = NULL; |
|---|
| 8 | SV * (*sv_from_gvalue) (const GValue * value) = NULL; |
|---|
| 9 | GClosure * (*perl_closure_new) (SV * callback, SV * data, gboolean swap) = NULL; |
|---|
| 10 | |
|---|
| 11 | /* Caller does not own return value */ |
|---|
| 12 | const char *owl_closure_init(void) |
|---|
| 13 | { |
|---|
| 14 | void *handle = NULL; |
|---|
| 15 | const char *res = "Unable to dlopen self - huh?"; |
|---|
| 16 | |
|---|
| 17 | handle = dlopen(NULL, RTLD_LAZY | RTLD_NOLOAD); |
|---|
| 18 | if(handle) { |
|---|
| 19 | gvalue_from_sv = dlsym(handle, "gperl_value_from_sv"); |
|---|
| 20 | sv_from_gvalue = dlsym(handle, "gperl_sv_from_value"); |
|---|
| 21 | perl_closure_new = dlsym(handle, "gperl_closure_new"); |
|---|
| 22 | /* ... */ |
|---|
| 23 | if (dlclose(handle) != 0 |
|---|
| 24 | || gvalue_from_sv == NULL |
|---|
| 25 | || sv_from_gvalue == NULL |
|---|
| 26 | || perl_closure_new == NULL) { |
|---|
| 27 | res = dlerror(); |
|---|
| 28 | } else { |
|---|
| 29 | res = NULL; |
|---|
| 30 | } |
|---|
| 31 | } |
|---|
| 32 | return res; |
|---|
| 33 | } |
|---|
| 34 | |
|---|
Note: See
TracBrowser
for help on using the repository browser.