2011-04-28 13 views
6

He escrito una biblioteca personalizada que implementa malloc/calloc/realloc/free utilizando los prototipos C estándar, y descubrí cómo compilarlo en un archivo así. Quiero probar la biblioteca al vincular una aplicación estándar contra ella? ¿Cuál sería una buena manera de hacer esto? Una vez que tengo una biblioteca en funcionamiento, supongo que puedo cargarla con LD_PRELOAD, pero ¿cómo hago para que mis funciones coexistan pero tienen prioridad sobre las de la biblioteca del sistema? Mis funciones necesitan hacer una llamada a malloc para que la memoria se ejecute, por lo que no puedo eliminar completamente stdlib ... ¿Ayuda?Compilación de un Malloc personalizado

+1

Estoy bastante seguro de que mi respuesta se basa en el uso del enlazador dinámico. – conartist6

Respuesta

4

Las funciones que intenta reemplazar son funciones C estándar, no macros, no llamadas al sistema. Por lo tanto, simplemente debe asignarle a sus funciones los mismos nombres y compilarlos en una biblioteca compartida.

Luego, use LD_PRELOAD para precargar su biblioteca antes de que comience el binario. Como todas las direcciones se resuelven una vez, el vinculador averiguará las direcciones de sus funciones y recordará sus nombres y no las buscará en la biblioteca estándar más adelante.

Este enfoque puede no funcionar si su programa está vinculado de forma estática con el tiempo de ejecución estándar. Además, no funcionará en Mac OS X ya que hay otra API para interpolación.

En Linux, por ejemplo, a fin de que sus funciones de co-existir (es decir, si quieres sistema malloc utilizar en su propia implementación de malloc), usted tiene que abrir la biblioteca estándar de forma manual utilizando dlopen, ver las funciones necesita allí usando dlsym y los llama más tarde por dirección.

+0

Pensé que me encontraría con más problemas pero después de eliminar la inclusión de la biblioteca estándar y cargar malloc y salir con dlsym todo compilado bien. ¡Gracias! – conartist6

+0

@ conartist6: De nada :) –

1

Si tiene control del código fuente que va a utilizar esta biblioteca, aquí hay una posibilidad. Use diferentes nombres de funciones: en lugar de malloc, por ejemplo, llámelo newCoolMalloc. Este método a veces es más simple y no depende de las opciones especiales del vinculador.

Luego en su código, use #define para hacer que el código llame al conjunto de funciones deseado. Puedes #define malloc para ser algo diferente. Por ejemplo:

#define malloc newCoolMalloc 
#define free newCoolFree 

Si hace eso, sin embargo, debe tener mucho cuidado de incluirlo constantemente. De lo contrario, corre el riesgo de utilizar stdlib malloc en un lugar y luego su propio libre en otro que conduce a errores desordenados. Una forma de ayudar a mitigar esa situación es (si es posible) en su propio código usar nombres personalizados para la asignación y funciones gratuitas. Entonces es más fácil asegurarse de que se está llamando al correcto. Puede definir los diversos nombres personalizados para sus propias funciones malloc o incluso las funciones stdlib malloc originales.

Por ejemplo, es posible utilizar mallocPlaceHolder como su nombre real en el código:

someThing = mallocPlaceHolder(nbytes); 

A continuación, sus define verían de la misma familia:

#define mallocPlaceHolder myCoolMalloc 

Si no hay función de la forma mallocPlaceHolder (y libre asociado) realmente existen, evita mezclar diferentes bibliotecas.

+0

Lamentablemente, esto no funciona para mí. Quiero probar mi asignador ejecutando la aplicación de otra persona usando esta biblioteca.Podría recompilar con esos incluye en teoría, pero el tiempo y el esfuerzo se guardarán con LD_PRELOAD. – conartist6

2

No escriba su malloc() en términos de malloc() - escríbalo usando sbrk, que obtiene memoria directamente del sistema operativo.

+0

sugerencia interesante. Lo miraré. – conartist6

+0

En algunos sistemas, 'sbrk()' ya no está disponible. Por ejemplo, en mi Mac OS X actual, el hombre dice 'Las funciones brk y sbrk son curiosidades históricas que quedaron de días anteriores a la llegada de la administración de memoria virtual . Y si se ve el origen completo de la función, es par más divertido: 'errno = ENOMEM; return ((void *) - 1); ' – achedeuzot

Cuestiones relacionadas