There are many possible reasons of this. Ranges from that you access objects not yet created (because order of creation of objects across different translation units is undefined) which i think is quite probable in this case, and ranges to an error on your build-environment.
To make a own function be called before other constructor function, you have a constructor (priority)
attribute described here. GCC keeps a priority for each files' constructor input section. And it links them in order of those priorities. In the linker script of my linux system, that code looks like this (output it using ld -verbose
):
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
You would want to give it a low priority to make it execute before other registered ctor functions having a higher priority number. However from the looks of it, it seems like constructors having no number will be executed first. Not sure entirely. Best you give it a try. If you want to have your function called even before _do_global_ctors_aux, you have to release the original _init
function that is normally executed when your program is loaded by the ELF loader (look into the -init
option of ld). It's been some time since i messed with it, but i remember it has to do some intimate details of initialization, so i wouldn't try to replace it. Try using the constructor attribute i linked to. However, be very careful. Your code will possibly be executed before other important objects like cout
are constructed.
Update: I did a test, and it actually executes ctor functions in reverse. So ctor functions that are linked first are executed later. This code happens to be in crtstuff.c of the gcc source code:
func_ptr *p;
for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
(*p) ();
I made a little test:
void dothat() { }
struct f {
f() { dothat(); }
} f_;
void doit() __attribute__((constructor (0)));
void doit() { }
int main() { }
Linking with --print-map
yields, among others, this output:
.ctors 0x080494f4 0x10
*crtbegin.o(.ctors)
.ctors 0x080494f4 0x4 /usr/lib/gcc/i686-pc-linux-gnu/4.3.2/crtbegin.o
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
.ctors 0x080494f8 0x4 /tmp/ccyzWBjs.o
*(SORT(.ctors.*))
.ctors.65535 0x080494fc 0x4 /tmp/ccyzWBjs.o
*(.ctors)
.ctors 0x08049500 0x4 /usr/lib/gcc/i686-pc-linux-gnu/4.3.2/crtend.o
Notice how .ctors.65535
is the section we implicitly created by our attribute priority 0
. Now, if you give it that priority, gcc warns and it's totally right :p
test.cpp:7: warning: constructor priorities from 0 to 100 are reserved for the implementation
I tested it by breaking on doit
and dothat
, and it called them in the order we expect. Have fun!