Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding _init function in C , how safe is it?

Tags:

c

linux

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

like image 841
SpotsWood Avatar asked Mar 29 '11 15:03

SpotsWood


2 Answers

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 after main() has completed or exit() 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.

like image 189
NPE Avatar answered Nov 14 '22 12:11

NPE


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.

like image 1
Thomas M. DuBuisson Avatar answered Nov 14 '22 10:11

Thomas M. DuBuisson