- if (!dlopen_ptr) {
- dlopen_ptr = (PFNDLOPEN)dlsym(RTLD_NEXT, "dlopen");
- if (!dlopen_ptr) {
- os::log("apitrace: error: dlsym(RTLD_NEXT, \"dlopen\") failed\n");
+#ifdef __GLIBC__
+ /*
+ * We rely on glibc's internal __libc_dlsym. See also
+ * http://www.linuxforu.com/2011/08/lets-hook-a-library-function/
+ *
+ * Use use it to obtain the true dlsym. We don't use __libc_dlsym directly
+ * because it does not support things such as RTLD_NEXT.
+ */
+ typedef void * (*PFN_DLSYM)(void *, const char *);
+ static PFN_DLSYM dlsym_ptr = NULL;
+ if (!dlsym_ptr) {
+ void *libdl_handle = _dlopen("libdl.so.2", RTLD_LOCAL | RTLD_NOW);
+ if (libdl_handle) {
+ dlsym_ptr = (PFN_DLSYM)__libc_dlsym(libdl_handle, "dlsym");
+ }
+ if (!dlsym_ptr) {
+ os::log("apitrace: error: failed to look up real dlsym\n");