This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Re: What does ld.so do that dlopen don't do when loading shared libraries
- From: Celelibi <celelibi at gmail dot com>
- To: OndÅej BÃlka <neleai at seznam dot cz>
- Cc: libc-help at sourceware dot org
- Date: Mon, 29 Apr 2013 22:09:27 +0200
- Subject: Re: What does ld.so do that dlopen don't do when loading shared libraries
- References: <CAJR2zJ-DZ+G-FZw_2SSTPjF-BVkEkmfO9EcSfbUjTa_xKbMcfg at mail dot gmail dot com> <20130428213419 dot GA30730 at domone dot kolej dot mff dot cuni dot cz> <CAJR2zJ85ehHFMzuYw1mNqjhdypAMhcDSxxag_BC=ew7BL5-OBg at mail dot gmail dot com> <CAJR2zJ8K=AQu4ikr2WXzxyFCh=KLwqBPJg5vASbuLx8wLoMVXA at mail dot gmail dot com>
(triple reply combo :p)
After a bit of investigation, it looks like it's not only TAU or
profilers that suffer from this bug, but every tool relying on
instrumentation by gcc.
gcc's option -finstrument-functions add calls to
__cyg_profile_func_enter@plt and __cyg_profile_func_exit@plt at the
begining and end of every function. Thus, a tool just have to define
the real functions and then can do whatever it want.
And the thing is that, even thought the calls to these PLT entries are
actually executed, execution never reach the actual functions (when
opened with dlopen). I tried to debug instruction-by-instruction, but
got lost inside ld-linux-x86-64.so.2.
I think it just refuse to resolve the symbol or something like that.
I think you should be able to explain a bit what happens. :)
Here I join a small example (independant of TAU or anything) to show
this behavior
Compilation commands:
gcc -shared -fPIC -finstrument-functions -o foo.so foo.c
gcc -ldl -o dyn dyn.c
(dyn.c didn't change, but I still join it for self-containment of this message.)
Regards,
Celelibi
#include <stdio.h>
#define _noinstr __attribute__((no_instrument_function))
_noinstr void __cyg_profile_func_enter(void *this_fn, void *call_site) {
printf("Entering\n");
}
_noinstr void __cyg_profile_func_exit(void *this_fn, void *call_site) {
printf("Exiting\n");
}
/* Just dummy computation and printf */
void foo(void) {
printf("Hello World!\n");
}
#include <dlfcn.h>
void foo(void);
int main(void) {
void *lib = dlopen("./foo.so", RTLD_LAZY);
void (*fun)(void);
if (!lib)
return 1;
*(void **)&fun = dlsym(lib, "foo");
if (!fun)
return 2;
fun();
if (dlclose(lib))
return 3;
return 0;
}