I want to call my custom malloc/new calls instead of standard library functions. 1. for malloc, I have this short program
#include <stdio.h>
#include <stdlib.h>
void *__real_malloc(size_t size);
void *__wrap_malloc(size_t size)
{
void *ptr = __real_malloc(size);
printf("malloc(%ld) = %p\n", size, ptr);
return ptr;
}
int main(void) {
int* ptr = (int*) malloc(sizeof(int));
return 0;
}
I use the following command to compile
g -Wl,--wrap,malloc main.cpp
But getting below error
/usr/bin/ld: /tmp/ccnB04KY.o: in function `__wrap_malloc(unsigned long)':
b3.cpp:(.text 0x18): undefined reference to `__real_malloc(unsigned long)'
/usr/bin/ld: /tmp/ccnB04KY.o: in function `main':
b3.cpp:(.text 0x54): undefined reference to `__wrap_malloc'
collect2: error: ld returned 1 exit status
This works with gcc for .c files but not with g and .cpp files. What's the issue?
2. Also I cant figure out how to overide new calls?
CodePudding user response:
Why does g
not work with -Wl,--wrap,malloc
?
g
is for C , and C ABI is different from C ABI. So you need to add extern "C"
around __real_malloc
and __wrap_malloc
:
extern "C" {
void *__real_malloc(size_t size);
void *__wrap_malloc(size_t size) {
void *ptr = __real_malloc(size);
printf("malloc(%ld) = %p\n", size, ptr);
return ptr;
}
}
C rewrites names to some kind of random (at least it seems so) strings to avoid conflicts, while C simply inserts _
before the "C" name to create a name in assembly. (This naming convention is called _cdecl
. It's default for C and is used most commonly.) extern "C"
forces C compiler to generate names according to C's convention. See https://en.wikipedia.org/wiki/Name_mangling for more information.
How to override new
?
You can override new
specifically for a class, or provide a global new
. See https://en.cppreference.com/w/cpp/memory/new/operator_new.
CodePudding user response:
If you are using glibc then you can use the GNU extensions for malloc: man malloc_hook
#include <malloc.h>
void *(*__malloc_hook)(size_t size, const void *caller);
void *(*__realloc_hook)(void *ptr, size_t size, const void *caller);
void *(*__memalign_hook)(size_t alignment, size_t size,
const void *caller);
void (*__free_hook)(void *ptr, const void *caller);
void (*__malloc_initialize_hook)(void);
void (*__after_morecore_hook)(void);
For new
you can provide a global new. See https://en.cppreference.com/w/cpp/memory/new/operator_new.