Objective
My application has a custom memory allocator. Also, that application includes an open source third party library. I need to have the third party's allocations/frees call into the custom memory allocator.
Specific Requirements
- Map the third party's: malloc, calloc, realloc, and free.
- Also map any other c functions that call the above functions. For example, strdup. strdup calls malloc.
- Pass in the calling function and line number into the custom allocation functions.
Original Implementation
The application has these functions defined: custom_malloc(), custom_calloc(), custom_realloc(), custom_strdup(), and custom_free()
The third party's allocation functions were mapped via these CFLAGS settings as part of the third party's build process.
export 'CFLAGS=-Dmalloc=custom_malloc -Dcalloc=custom_calloc -Drealloc=custom_realloc -Dstrdup=custom_strdup -Dfree=custom_free'
These custom functions are not referenced anywhere else in the third party library.
Issues with Original Implementation
Does not overwrite other potential c functions that do allocations. i.e. The above flags just seem to do a text based replacement. Any "built-in" functions will not be handled.
eg. strdup was actually found to be an issue later on when it was realized that there was a custom_free done for the memory with no matching custom allocation. strdup under the covers just calls malloc but the CFLAGS replacement didn't replace that malloc call.
Another issue is that the calling function and line number is not passed in.
LD_PRELOAD
My understanding is that LD_PRELOAD is another mechanism to overwrite malloc, calloc, realloc, and free. And it does it in such a way that strdup's (and any other function's) malloc will also be overwritten.
My Attempted Implementation with LD_PRELOAD (Linking issue and does not fulfill the requirement to pass in the calling function and line number)
In a c file separate from the custom application and also the third party library, I re-implemented malloc(), which just points back to the application's custom_malloc() function.
memory_manager.c
extern void *custom_malloc(size_t size);
void *malloc(size_t size)
{
return custom_malloc(size);
}
Built it with
gcc -Wall -fPIC -shared -o memory_manager.so memory_manager.c -ldl
And then set LD_PRELOAD while building the open source library
export LD_PRELOAD=memory_manager.so
When trying to build the open source library, I see this failure
/usr/bin/env: symbol lookup error: .../memory_manager.so: undefined symbol: custom_malloc
I am a little surprised that it is complaining about custom_malloc not yet being defined since the CFLAGS method worked.
Is there some additional step that I need to do here? Or am I going the wrong direction?
Next Planned Step (if the above had/will work)
I was going to re-write memory_manager.c as follows and then implement calloc, realloc, and free in a similar manner (and strdup, if that is allowed with LD_PRELOAD. So that I can get the caller of strdup not strdup's malloc).
memory_manager.c
extern void *custom_malloc(size_t size, char *file_name, int line_number);
#define malloc(SZ) custom_malloc(SZ, __FILE__, __LINE__)