@@ -511,28 +511,52 @@ static const char * vmprof_error = NULL;
511
511
static void * libhandle = NULL ;
512
512
513
513
#ifdef VMPROF_LINUX
514
+ #include <link.h>
514
515
#define LIBUNWIND "libunwind.so"
515
516
#ifdef __i386__
516
517
#define PREFIX "x86"
518
+ #define LIBUNWIND_SUFFIX ""
517
519
#elif __x86_64__
518
520
#define PREFIX "x86_64"
521
+ #define LIBUNWIND_SUFFIX "-x86_64"
519
522
#endif
520
523
#define U_PREFIX "_U"
521
524
#define UL_PREFIX "_UL"
522
525
#endif
523
526
524
527
int vmp_native_enable (void ) {
525
528
#ifdef VMPROF_LINUX
529
+ void * oldhandle = NULL ;
530
+ struct link_map * map = NULL ;
526
531
if (libhandle == NULL ) {
527
532
// on linux, the wheel includes the libunwind shared object.
528
- libhandle = dlopen (NULL , RTLD_LAZY | RTLD_LOCAL );
533
+ libhandle = dlopen (NULL , RTLD_NOW );
529
534
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 ;
532
542
}
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 );
533
556
libhandle = NULL ;
534
557
}
535
558
559
+ // fallback! try to load the system's libunwind.so
536
560
if ((libhandle = dlopen (LIBUNWIND , RTLD_LAZY | RTLD_LOCAL )) == NULL ) {
537
561
goto bail_out ;
538
562
}
0 commit comments