2011-03-29 6 views
5

Estoy construyendo una herramienta de memoria de depuración en forma de una biblioteca compartida que enlace contra un ejecutable en tiempo de ejecución (incluye métodos anulados de la familia malloc). Para manejar las inicializaciones de mis estructuras de datos, simplemente uso una variable de condición. Cada vez que se llama mi malloc, verifico si la variable no está configurada y luego llamo a una función responsable de inicializar mis estructuras. Ahora esto funciona bien para programas que ejecutan un solo hilo de ejecución, pero surgen problemas si un programa incluye más de 1 hilo.Anulación de la función _init en C, ¿qué tan seguro es?

La única forma (puedo pensar) de asegurarme de que la inicialización ocurre antes de que el usuario engendre algún hilo es anular _init como se muestra en in this link.

Ahora bien, este pequeño ejemplo pasa justo pero cuando intento de anular _init en mi propia libary compartida consigo este error al intentar vincularlo:

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 

utilizo exactamente los mismos pasos que en el ejemplo de el enlace, es solo que mi biblioteca compartida también incluye un conjunto de variables globales y versiones anuladas de malloc/free etc.

¿Alguien me puede dar una indicación de lo que está pasando mal? Además, ¿hay algo más que tener en cuenta al anular _init (supongo que no es algo muy normal de hacer).

Gracias

Respuesta

9

echar un vistazo a la siguiente página de preguntas frecuentes:

http://www.faqs.org/docs/Linux-HOWTO/Program-Library-HOWTO.html#INIT-AND-CLEANUP

Describe _init/_fini como peligrosa y obsoleta, y recomienda que __attribute__ ((constructor))__attribute__ ((destructor)) y se utilizan en su lugar.

Desde el gcc manual:

constructor (priority) destructor (priority)

El atributo constructor hace que la función que se llamará automáticamente antes de la ejecución entra main(). De forma similar, el atributo destructor hace que la función se llame automáticamente después de que se haya completado o se haya llamado al exit(). Las funciones con estos atributos son útiles para inicializar datos que se usarán implícitamente durante la ejecución del programa . Puede proporcionar una prioridad de entero opcional para controlar el orden en que se ejecutan las funciones constructor y destructor . Un constructor con un número de prioridad más pequeño se ejecuta antes de un constructor con un número de prioridad más grande ; la relación opuesta contiene para destructores. Por lo tanto, si tiene un constructor que asigna un recurso y un destructor que desasigna el mismo recurso, ambas funciones suelen tener la misma prioridad .Las prioridades para las funciones constructor y destructor son las mismas que las especificadas para namespace-scope C++ objects (ver C++ Atributos).

Estos atributos no están actualmente implementados para Objective-C.

1

1) Usted puede escribir su propio _init o principal:

GNU GCC le permite definir su propia función del mismo nombre que un símbolo existente. Al vincular, proporciona un argumento de -Xlinker --wrap=<symName>. Pretendiendo que hizo esto a principal, puede llamar a la principal real a través de __real_main(...):

int main(int argc, void *argv) 
{ 
    // any code you want here 
    return __real_main(argc,argv); 
} 

2) Usted puede escribir su propio enlazador dinámico. Si lo hace, configure la sección .interp para que apunte al objeto compartido que contiene su enlazador/cargador dinámico.

0

Para superar ese error, compile el código como gcc -nostartfiles memory2.c -o memory2, aquí omitimos el constructor y el destructor.

Pero no se recomienda anular estos.

Cuestiones relacionadas