This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: LD_PRELOAD and attribute constructor


On 6/2/09, David Hagood <david.hagood@gmail.com> wrote:
> You really cannot count upon the execution order of constructors across
>  compilation units. All that is guaranteed is that within one compilation
>  unit (one source file) the constructors will execute in order. When you
>  are dealing with more than one compilation unit - all bets are off: all
>  that is guaranteed is that all static constructors will be called before
>  main is called, but in what order? No guarantees.

Understood. I guess I was expecting the libraries to be loaded more like this:

foreach library foo {
     add functions in foo to program link table
     call ctors in foo
}

Rather than:

foreach library foo {
    add functions in foo to program link table
    add ctors to ctor_list
}
foreach ctor in ctor_list {
   call ctor
}

(I don't know how it actually works, this is just how it seems to
behave). My problem occurs because the other library's ctor gets
called before the wrapper's, but the wrapper's version of fopen() is
already linked in. If the first case were used, I wouldn't care which
ctor was called first. Any reason to prefer the second implementation
over the first?

>
>  As for the idea of "any ctor like function in a module will be called
>  before any functions in the module are called" - how do you expect that
>  could work? What if a file defines 2 ctor functions, the first of which
>  calls a function within the file? How, then, can both ctor functions be
>  called before the call of the normal function, when it is the first ctor
>  that calls the function?

Ahh, good point. I guess my definition wasn't particularly clear. When
I look at wrap.c, I trace the variable s_fopen as follows:
 1) declared static, it starts as 0
 2) wrap_init() is a ctor, so that runs next and sets it to dlsym(...)
 3) fopen() can be called at anytime now

So despite my silly definition, I don't mind that the ctor in step 2
can call other non-ctor functions - that's easy enough to see within a
single file. The fact that another library's ctor can call fopen()
breaks my assumption that 2) must happen before 3), which was quite
confusing given that several of the examples I've found of LD_PRELOAD
overloading use the ctor approach to set the function pointers.

Thanks for the help!
-Mike


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]