Reputation: 354
I've come across a small problem while monitoring malloc and free trough the use of function interposition.
When performing the function interposition for just malloc, it works as exepcted. However, when trying to interpose free as well it ends up in a loop; i seems like free is recursivly invoked but i just dont know why.
This is the code for the malloc and free functions. (mod_malloc_free.c)
#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <dlfcn.h>
void* malloc(size_t size) {
static void* (*real_malloc)(size_t) = NULL;
printf("%s\n", "inside shared malloc");
if(!real_malloc)
real_malloc = dlsym(RTLD_NEXT, "malloc");
void * p = real_malloc(size);
printf("malloc(%d) = %p\n",size, p );
printf("%s\n", "returning from shared malloc");
return p;
}
void free(void* ap ) {
static void (*real_free)(void*) = NULL;
printf("inside shared free...\n");
if(!real_free)
real_free = dlsym(RTLD_NEXT, "free");
printf("free = %p\n", ap);
real_free(ap);
}
The main simply consists of:
#include <stdio.h>
#include <malloc.h>
int main(void) {
void * p = malloc(123);
printf("p = %p\n",p );
free(p);
return 0;
}
Compiled as:
gcc -shared -ldl -fPIC mod_malloc_free.c -o libcustom.so
gcc -o smallMain -Wall smallMain.c
LD_PRELOAD=./libcustom.so ./smallMain
Best regards
Nyfiken
Upvotes: 2
Views: 1069
Reputation: 222908
It is likely printf
is calling free
. Of course, that implies it also performs memory allocation, so it raises the question why do you not see recursive calls in malloc
. Likely printf
is calling an alternative such as calloc
or realloc
.
To interpose in just your own code, use macros to replace the calls or link your code separately and use linker features to remove your malloc
and free
before linking with external libraries (such as the -unexported_symbol
switch for the Apple version of ld).
To interpose in all code, remove printf
from your routines. Call simpler routines, such as fputs
instead. Alternatively, use a static flag to suppress the recursion:
void free(void *ap)
{
static void (*RealFree)(void *) = 0;
If (!RealFree)
RealFree = dlsym(RTLD_NEXT, "free");
static int InsideCall = 0;
if (!InsideCall)
{
InsideCall = 1;
… Do stuff…
InsideCall = 0;
}
}
(If you have multiple threads or exception handlers that perform memory allocation, additional steps must be taken.)
Upvotes: 2
Reputation: 129374
I would suggest that you use a macro to replace malloc/free with your own functions, instead of using function pointers.
Something like this should do it:
#ifdef REPLACE_MALLOC
#define malloc(x) my_mallc(x)
#define free(x) my_free(x)
#endif
Don't forget to do:
#undef malloc
#undef free
before your actual implementation.
Note however that technically this is not "proper" - you are not supposed to use macros for things that are part of a standard library, so please don't come moaning here if it stops working - in particular, Microsoft already does something like this to replace malloc
with it's debug version in debug builds.
Upvotes: 0
Reputation: 5463
glibc provides the real symbol (not weak) with __
prefix. So try to lookup symbol __malloc
and __free
.
And just to prevent recursion, don't use printf() or any other functions that might need to allocate memory inside your wrapper.
Upvotes: 1