Skip to content

Commit 5b9c707

Browse files
committed
the main programs handle does not provide enough information to call dlsym and find references to libunwind. An extra step extracts the path to the wheel's libunwind.so
1 parent 4175c5b commit 5b9c707

File tree

1 file changed

+27
-3
lines changed

1 file changed

+27
-3
lines changed

src/vmp_stack.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -511,28 +511,52 @@ static const char * vmprof_error = NULL;
511511
static 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

524527
int 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

Comments
 (0)