Problem in overriding malloc

后端 未结 9 1980
一整个雨季
一整个雨季 2020-12-30 09:24

I am trying to override malloc by doing this.

#define malloc(X) my_malloc((X))

void* my_malloc(size_t size)
{

    void *p = malloc(size);
    printf (\"All         


        
相关标签:
9条回答
  • 2020-12-30 09:29

    What if you implemented my_malloc() in a different file that doesn't see the #Define?

    0 讨论(0)
  • 2020-12-30 09:35

    With Glibc, there exists malloc_hook(3) as the proper way to globally interpose your own malloc function.

    #include <stdio.h>
    #include <malloc.h>
    
    static void *(*old_malloc_hook)(size_t, const void *);
    
    static void *new_malloc_hook(size_t size, const void *caller) {
        void *mem;
    
        __malloc_hook = old_malloc_hook;
        mem = malloc(size);
        fprintf(stderr, "%p: malloc(%zu) = %p\n", caller, size, mem);
        __malloc_hook = new_malloc_hook;
    
        return mem;
    }
    
    static void init_my_hooks(void) {
        old_malloc_hook = __malloc_hook;
        __malloc_hook = new_malloc_hook;
    }
    
    void (*__malloc_initialize_hook)(void) = init_my_hooks;
    
    $ cat >mem.c <<'EOF'
    (the code above)
    EOF
    $ cat >main.c <<'EOF'
    #include <stdio.h>
    #include <stdlib.h>
    int main() {
        char *buf = malloc(50);
        sprintf(buf, "Hello, world!");
        puts(buf);
        free(buf);
        return 0;
    }
    EOF
    $ cc mem.c main.c
    $ ./a.out
    0x40077e: malloc(50) = 0x22f7010
    Hello, world!
    

    (We could use __attribute__((constructor)), but that trick isn't necessary: Glibc handily provides __malloc_initialize_hook as another way to load run code before main.)

    0 讨论(0)
  • 2020-12-30 09:35

    Unlike for new/delete, there is no standard way to override malloc and free in standard C or C++.

    However, most platforms will somehow allow you to repace these standard library functions with your own, for example at link time.

    If that doesn't work, and portability is necessary, first declare the functions, then declare the defines:

    #include <stdlib.h>
    
    void *myMalloc(size_t size) {
        // log
        return (malloc)(size);
    }
    
    void myFree(void *ptr) {
        // log
        (free)(ptr);
    }
    
    #define malloc(size) myMalloc(size)
    #define free(ptr) myFree(ptr)
    
    0 讨论(0)
  • 2020-12-30 09:41

    Problem solved:

    void* my_malloc(size_t size, const char *file, int line, const char *func)
    {
    
        void *p = malloc(size);
        printf ("Allocated = %s, %i, %s, %p[%li]\n", file, line, func, p, size);
        return p;
    }
    #define malloc(X) my_malloc( X, __FILE__, __LINE__, __FUNCTION__)
    
    0 讨论(0)
  • 2020-12-30 09:43

    To fix both the macro-replacement problem, and make LINE etc work as you're hoping they will:

    #define malloc(X) my_malloc((X), __FILE__, __LINE__, __FUNCTION__)
    
    void* my_malloc(size_t size, const char *f, int l, const char *u)
    {
    
        void *p = (malloc)(size);
        printf ("Allocated = %s, %d, %s, %x\n", f, l, u, p);
        return p;
    }
    

    (That way LINE and friends will be evaluated where the macro is expanded - otherwise they'd always be the same).

    Enclosing the name (malloc) in parantheses prevents the macro malloc from being expanded, since it is a function-like macro.

    0 讨论(0)
  • 2020-12-30 09:44

    #define is a macro replacement. The call to malloc(size) is getting replaced by my_malloc(size).

    0 讨论(0)
提交回复
热议问题