usar - Crear una función de envoltura para malloc y gratuita en C
memoria dinamica en c (9)
Oye, estoy intentando crear funciones de envoltura gratis y malloc en C para ayudarme a notificarme sobre las pérdidas de memoria. ¿Alguien sabe cómo declarar estas funciones así que cuando llamo a malloc () y libre () llamará a mis funciones personalizadas y no a las funciones lib estándar?
Aquí hay un conjunto de funciones de envoltura que utilicé durante años (y aún lo hago cuando busco en C) para detectar memoria sin liberar, memoria libre varias veces, referencias a memoria libre, desbordamientos / desbordamientos de búfer, y liberar memoria que no fue asignado.
ftp://ftp.digitalmars.com/ctools.zip
Han existido por 25 años y han demostrado su valía.
Podría usar el preprocesador de macro para redefinir malloc y usar los paquetes de mem gratuitos, pero recomiendo que no lo haga, ya que no redirigirá las llamadas de biblioteca a malloc como lo hace strdup.
En C, el método que utilicé fue similar a:
#define malloc(x) _my_malloc(x, __FILE__, __LINE__)
#define free(x) _my_free(x)
Esto me permitió detectar la línea y el archivo de donde se asignó la memoria sin demasiada dificultad. Debe ser multiplataforma, pero encontrará problemas si la macro ya está definida (lo cual solo debería ser el caso si está usando otro detector de fuga de memoria).
Si desea implementar lo mismo en C ++, el procedimiento es un poco más complex pero usa el mismo truco.
Perdón por reabrir una publicación de 7 años.
En mi caso, necesitaba envolver memalign / aligned_malloc en malloc. Después de probar otras soluciones, terminé implementando la que se detalla a continuación. Parece estar funcionando bien.
/*
* Link-time interposition of malloc and free using the static
* linker''s (ld) "--wrap symbol" flag.
*
* Compile the executable using "-Wl,--wrap,malloc -Wl,--wrap,free".
* This tells the linker to resolve references to malloc as
* __wrap_malloc, free as __wrap_free, __real_malloc as malloc, and
* __real_free as free.
*/
#include <stdio.h>
void *__real_malloc(size_t size);
void __real_free(void *ptr);
/*
* __wrap_malloc - malloc wrapper function
*/
void *__wrap_malloc(size_t size)
{
void *ptr = __real_malloc(size);
printf("malloc(%d) = %p/n", size, ptr);
return ptr;
}
/*
* __wrap_free - free wrapper function
*/
void __wrap_free(void *ptr)
{
__real_free(ptr);
printf("free(%p)/n", ptr);
}
Puede hacer la función de envoltura y "sobrescribir" con LD_PRELOAD, de forma similar al ejemplo que se muestra anteriormente.
LD_PRELOAD=/path.../lib_fake_malloc.so ./app
Pero recomiendo hacer esto "un poco" más inteligente, me refiero a llamar a dlsym una vez .
#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <dlfcn.h>
void* malloc(size_t size)
{
static void* (*real_malloc)(size_t) = NULL;
if (!real_malloc)
real_malloc = dlsym(RTLD_NEXT, "malloc");
void *p = real_malloc(size);
fprintf(stderr, "malloc(%d) = %p/n", size, p);
return p;
}
ejemplo que he encontrado aquí: http://www.jayconrod.com/cgi/view_post.py?23 publicación de Jay Conrod.
Pero lo que he encontrado realmente genial en esta página es que: el enlazador GNU proporciona una opción útil, - wrap . Cuando verifico "man ld" hay un ejemplo siguiente:
void *
__wrap_malloc (size_t c)
{
printf ("malloc called with %zu/n", c);
return __real_malloc (c);
}
Estoy de acuerdo con ellos que es un "ejemplo trivial" :). Incluso dlsym no es necesario.
Permítanme citar una parte más de mi página "man ld":
--wrap=symbol
Use a wrapper function for symbol.
Any undefined reference to symbol will be resolved to "__wrap_symbol".
Any undefined reference to "__real_symbol" will be resolved to symbol.
Espero, la descripción está completa y muestra cómo usar esas cosas.
Si define sus propias funciones para malloc () y free () y lo vincula explícitamente con sus aplicaciones, sus funciones se deben usar con preferencia a las de la biblioteca.
Sin embargo, su función llamada ''malloc'' no puede llamar a la función de biblioteca malloc, porque en ''c'' no hay concepto de espacios de nombres separados. En otras palabras, tendrías que implementar las partes internas de Malloc y liberarte.
Otro enfoque sería escribir las funciones my_malloc () y my_free (), que llaman a las de la biblioteca estándar. Esto significa que cualquier código que llame a malloc tendría que ser cambiado para llamar a sus funciones my_xxx.
Si está utilizando Linux, puede usar malloc_hook () (con GNU glibc). Esta función le permite a malloc llamar a su función antes de llamar al malloc real. La página man tiene un ejemplo sobre cómo usarla.
Si solo habla de la memoria que tiene bajo control, es decir, que está malloc y libre por sí mismo, puede echar un vistazo a rmdebug . Probablemente sea lo que va a escribir de todos modos, para que pueda ahorrar en algún momento. Tiene una licencia muy liberal, si eso debería ser importante para usted.
Yo personalmente lo uso en un proyecto, para buscar fugas de memoria, lo bueno es que es mucho más rápido que valgrind, sin embargo, no es tan potente por lo que no obtienes la pila de llamadas completa.
Tienes pocas opciones:
Solución específica de GLIBC (principalmente Linux). Si su entorno de compilación es
glibc
congcc
, la forma preferida es usar los ganchos malloc . No solo le permite especificarmalloc
personalizado yfree
, sino que también identificará al que llama por la dirección de retorno en la pila.Solución específica POSIX. Defina
malloc
yfree
como envoltorios para las rutinas de asignación originales en su ejecutable, lo que "anulará" la versión de libc. Dentro del contenedor puede llamar a la implementación original demalloc
, que puede buscar usandodlsym
con el manejadorRTLD_NEXT
. Su aplicación o biblioteca que define las funciones de contenedor debe vincularse con-ldl
.#define _GNU_SOURCE #include <dlfcn.h> #include <stdio.h> void* malloc(size_t sz) { void *(*libc_malloc)(size_t) = dlsym(RTLD_NEXT, "malloc"); printf("malloc/n"); return libc_malloc(sz); } void free(void *p) { void (*libc_free)(void*) = dlsym(RTLD_NEXT, "free"); printf("free/n"); libc_free(p); } int main() { free(malloc(10)); return 0; }
Linux específico. Puede anular las funciones de bibliotecas dinámicas de forma no invasiva si las especifica en la variable de entorno
LD_PRELOAD
.LD_PRELOAD=mymalloc.so ./exe
Mac OSX específico.
Igual que Linux, excepto que
DYLD_INSERT_LIBRARIES
la variable de entornoDYLD_INSERT_LIBRARIES
.