2

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__)
user1266174
  • 111
  • 2
  • 11
  • To me, it's hard to follow (lacks focus, and detail). You said you get the error when building the open source library, but you only told us about custom_malloc in connection with memory_manager. What used to be isn't relevant. – Allan Wind Sep 11 '22 at 00:33
  • Thanks @AllanWind I have updated it to be more coherent and linear in thought. Some more detail added. – user1266174 Sep 11 '22 at 02:23
  • Would you mind to provide a [mre], with emphasis on "complete"? -- BTW, of course, preprocessor macros are just text replacements, there is no magic. But to have source file name and line number, you need the preprocessor. -- I don't understand how an original `strdup()` is called if you replace it with your `custom_strdup()`. – the busybee Sep 11 '22 at 09:12

0 Answers0