使用LD_PRELOAD加载malloc free wrapper库

1.测试程序编译运行

测试代码test.c

#include <stdio.h>
#include <stdlib.h>

int main(){
    printf("main func addr:%p\n", main);
    printf("start malloc\n");
    char * pc1 = malloc(10);
    char * pc2 = malloc(10);
    printf("start free\n");
    free(pc1);
}

compile & run:

    $gcc -g -O0 -o test test.c
    $./test

output:

main func addr:0x55582f4ff1a9
start malloc
start free

2.编写实现mymalloc,编译运行

mymalloc.c 代码:

#define _GNU_SOURCE
#include <dlfcn.h>
#include <stddef.h>
#include <stdio.h>

static void *(*real_malloc)(size_t) = NULL;
static void (*real_free)(void *) = NULL;

static void __attribute__((constructor)) init(void)
{
    real_malloc = (void *(*)(size_t))dlsym(RTLD_NEXT, "malloc");
    real_free = (void (*)(void *))dlsym(RTLD_NEXT,"free");
}

void *malloc(size_t len)
{
    static __thread int no_hook = 0;

    if (no_hook)
    {
        return (*real_malloc)(len);
    }

    void * caller = (void *)(long)__builtin_return_address(0);
    no_hook = 1;
    printf("malloc call %zu from %p\n", len, caller); //printf call malloc internally
    no_hook = 0;

    void * ret = (*real_malloc)(len);
    return ret;
}

void free(void *ptr){ 
    void * caller = (void *)(long)__builtin_return_address(0);
    printf("free call %p from %p\n", ptr, caller);
    (*real_free)(ptr);
}

compile & run:

    $gcc -g -O0 -fPIC -shared mymalloc.c -o libmymalloc.so -ldl
    $LD_PRELOAD=./libmymalloc.so ./test

output:

    malloc call 1024 from 0x7f4da2cead04
    free call 0x560e64ead2a0 from 0x7f4da2cfae75
    main func addr:0x560e6462f1a9
    start malloc
    malloc call 10 from 0x560e6462f1e3
    malloc call 10 from 0x560e6462f1f1
    start free
    free call 0x560e64eadac0 from 0x560e6462f20d

3.进一步分析调用栈

malloc call 10 from 0x560e6462f1e3,其中0x560e6462f1e3代表哪个函数?

我们先看test中main函数地址是:

    $nm test | grep main            
    00000000000011a9 T main

我们先看main函数运行时地址:main func addr:0x560e6462f1a9
那么编译地址到运行地址的转换则是:0x560e6462f1a9-00000000000011a9=0x560E6462E000

那么0x560e6462f1e3的调用栈是什么呢?
0x560e6462f1e3-0x560E6462E000=0x11E3

    $addr2line -e test -afsp 0x11E3
    0x00000000000011e3: main at test.c:7

可以看出0x560e6462f1e3的调用栈是:main at test.c:7

4.reference

https://www.jianshu.com/p/bd819ce58c60
https://www.cnblogs.com/net66/p/5609026.html
https://stackoverflow.com/questions/42336616/fixing-the-recursive-call-to-malloc-with-ld-preload

版权声明:本文为weixin_45609638原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。