Overriding _init function in C , how safe is it?
I am building a debugging memory tool in a form of a shared library which I link against an executable at run time(includes overrided methods of malloc family). To handle initializations of my data structures I simple use a condition variable. Every time my malloc is called I check if the variable is not set and then I call a function responsible for initializing my structures. Now this works fine for programs running a single thread of execution but problems arise if a program includes more than 1 thread.
The only way (I can think of) to be sure that initialization happens before the user spawns any threads is to override _init as shown in this link.
Now this small example runs right but when I try to override _init on my own shared libary I get this error when trying to link it :
memory2.o: In function `_init':
memory2.c(.text+0x0): multiple definition of `_init'
/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/crti.o(.init+0x0):
开发者_开发百科 first defined here
collect2: ld returned 1 exit status
I use exactly the same steps as in the example from the link, it's just that my shared library also includes a set of global variables and overrided versions of malloc/free etc.
Anyone can give me a pointer of what's going wrong? Furthermore , is there anything else to take into consideration when overriding _init ( I am guessing it's not a very normal thing to do).
Thank you
Take a look at the following FAQ page:
http://www.faqs.org/docs/Linux-HOWTO/Program-Library-HOWTO.html#INIT-AND-CLEANUP
It describes _init/_fini
as dangerous and obsolete, and recommends that __attribute__ ((constructor))
and __attribute__ ((destructor))
are used instead.
From the gcc
manual:
constructor (priority)
destructor (priority)
The constructor attribute causes the function to be called automatically before execution enters
main()
. Similarly, the destructor attribute causes the function to be called automatically aftermain()
has completed orexit()
has been called. Functions with these attributes are useful for initializing data that will be used implicitly during the execution of the program. You may provide an optional integer priority to control the order in which constructor and destructor functions are run. A constructor with a smaller priority number runs before a constructor with a larger priority number; the opposite relationship holds for destructors. So, if you have a constructor that allocates a resource and a destructor that deallocates the same resource, both functions typically have the same priority. The priorities for constructor and destructor functions are the same as those specified for namespace-scope C++ objects (see C++ Attributes).These attributes are not currently implemented for Objective-C.
1) You can write your own _init or main:
GNU GCC allows you to define your own function of the same name as an existing symbol. When linking, you provide an argument of -Xlinker --wrap=<symName>
. Pretending you did this to main, you can call the real main via __real_main(...)
:
int main(int argc, void *argv)
{
// any code you want here
return __real_main(argc,argv);
}
2) You can write your own dynamic linker. If you do this then set the .interp section to point to the shared object containing your dynamic linker/loader.
To overcome that error compile the code as gcc -nostartfiles memory2.c -o memory2
, here we are skipping the constructor and destructor.
But it is not recommended to override these.
精彩评论