Wrapping C functions
Let's say you want to overwrite an API-function located in a library that you don't have any control over or a standard
library function. This is useful when you want to stub that function in some test bench or insert debugging information
in the function itself. To do this, we can make use of C-macros. Let's say we want to overwrite malloc
. We first
define our own malloc like so:
void* my_malloc(size_t size)
{
printf("my_malloc");
return NULL;
}
Then we can define the following macro to replace all instances of malloc
with our newly defined my_malloc
:
#define malloc my_malloc
Compiling and running yields us:
> clang main.c && ./a.out
my_malloc
What if we want to make use of the original malloc
in our newly created my_malloc
? This could be problematic as the define replaces all instances of malloc
with my_malloc
. So creating a my_malloc
like this will cause the macro to be recursively executed:
void* my_malloc(size_t size)
{
printf("my_malloc");
return malloc(size);
}
Compling and running this instead will result in:
> clang main.c && ./a.out
my_mallocmy_mallocm...y_malloSegmentation fault (core dumped)
Where the dots represent my_malloc
being printed MANY times.
To make this work, we have to place my_malloc
in a separate source file. Since source files are preprocessed to
translation units along with all the includes and compiled separately from each other, a define in e.g., main.c
will not affect a wrapper in e.g., malloc.c
. So we create the following files:
// malloc.c
void* my_malloc(size_t size)
{
printf("my_malloc");
return malloc(size);
}
// main.c
#define malloc my_malloc
void* my_malloc(size_t size);
int main(int)
{
void* ptr = malloc(4);
return 0;
}
Now it is possible to compile and execute without all those recursive calls:
> clang main.c malloc.c && ./a.out
my_malloc
We can now wrap the function declaration in a header file and include it wherever we want to
overwrite malloc
:
// malloc.h
#define malloc my_malloc
void* my_malloc(size_t size);