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: Ãngel GonzÃlez <keisial at gmail dot com>
- Cc: OndÅej BÃlka <neleai at seznam dot cz>, libc-help at sourceware dot org
- Date: Tue, 30 Apr 2013 02:06:05 +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> <CAJR2zJ9rOGpA0PNo_dPw_EeBmpM-Y3RLE0HTB8NC5sBkQa6_og at mail dot gmail dot com> <517EEF00 dot 8060805 at gmail dot com>
2013/4/30, Ãngel GonzÃlez <keisial@gmail.com>:
> On 29/04/13 22:09, Celelibi wrote:
>> (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
> Yes, it's strange. (I confirm the observed behavior)
>
> Kind of a workaround, if you do:
> LD_PRELOAD=$PWD/foo.so ./dyn
>
> Then the profile_funcs are called. Which supports your assumption, as
> foo.so is loaded by ld.so in that case.
> I have no idea why it does so. Looks as if dlopen() missed doing something.
>
>
Oh god, I think I found out.
The glibc actually define a default __cyg_profile_func_* that does nothing.
I'm not completely aware of the symbol resolution process, but I think
it take libraries in the order they were loaded. As libc always appear
last in the dependancies of an ELF, it shouldn't be a problem and the
libc implementation of these functions are called only when no other
symbol is found with this name.
And I think dlopen put the new library *after* libc. And thus the
symbol resolution fails to find the right implementation.
And LD_PRELOAD would work because it put the library *before* any other.
Addendum: "LD_DEBUG=symbols ./dyn" confirms this theory.
Is there a mechanism that could say "this symbol have a high/low
priority"? Weak symbols? (I don't exactly know what they do.) In that
case, I think a low priority should be applied to the libc definition
of these functions. My small tests shows that even with a weak symbol
in the libc I should define LD_DYNAMIC_WEAK=1. But at least that would
give me a chance. :)
I see the dlopen option RTLD_DEEPBIND which make things work, but
would imply that I modify the real application code that does a
dlopen, which I can't (I could still submit a bug, thought).
Well, that's all the solutions I see. Did I miss something?
Celelibi