@@ -511,28 +511,52 @@ static const char * vmprof_error = NULL;
511511static void * libhandle = NULL ;
512512
513513#ifdef VMPROF_LINUX
514+ #include <link.h>
514515#define LIBUNWIND "libunwind.so"
515516#ifdef __i386__
516517#define PREFIX "x86"
518+ #define LIBUNWIND_SUFFIX ""
517519#elif __x86_64__
518520#define PREFIX "x86_64"
521+ #define LIBUNWIND_SUFFIX "-x86_64"
519522#endif
520523#define U_PREFIX "_U"
521524#define UL_PREFIX "_UL"
522525#endif
523526
524527int vmp_native_enable (void ) {
525528#ifdef VMPROF_LINUX
529+ void * oldhandle = NULL ;
530+ struct link_map * map = NULL ;
526531 if (libhandle == NULL ) {
527532 // on linux, the wheel includes the libunwind shared object.
528- libhandle = dlopen (NULL , RTLD_LAZY | RTLD_LOCAL );
533+ libhandle = dlopen (NULL , RTLD_NOW );
529534 if (libhandle != NULL ) {
530- if (dlsym (libhandle , U_PREFIX PREFIX "_getcontext" ) != NULL ) {
531- goto loaded_libunwind ;
535+ // load the link map, it will contain an entry to
536+ // .libs_vmprof/libunwind-...so, this is the file that is
537+ // distributed with the wheel.
538+ if (dlinfo (libhandle , RTLD_DI_LINKMAP , & map ) != 0 ) {
539+ (void )dlclose (libhandle );
540+ libhandle = NULL ;
541+ goto bail_out ;
532542 }
543+ // grab the new handle
544+ do {
545+ if (strstr (map -> l_name , ".libs_vmprof/libunwind" LIBUNWIND_SUFFIX ) != NULL ) {
546+ oldhandle = libhandle ;
547+ libhandle = dlopen (map -> l_name , RTLD_LAZY |RTLD_LOCAL );
548+ (void )dlclose (oldhandle );
549+ oldhandle = NULL ;
550+ goto loaded_libunwind ;
551+ }
552+ map = map -> l_next ;
553+ } while (map != NULL );
554+ // did not find .libs_vmprof/libunwind...
555+ (void )dlclose (libhandle );
533556 libhandle = NULL ;
534557 }
535558
559+ // fallback! try to load the system's libunwind.so
536560 if ((libhandle = dlopen (LIBUNWIND , RTLD_LAZY | RTLD_LOCAL )) == NULL ) {
537561 goto bail_out ;
538562 }
0 commit comments