7.13.1 编译时打桩

7.13.1 编译时打桩

图 7-20 展示了如何使用 C 预处理器在编译时打桩。mymalloc.c 中的包装函数(图 7-20c)调用目标函数,打印追踪记录,并返回。本地的 malloc.h 头文件(图 7-20b)指示预处理器用对相应包装函数的调用替换掉对目标函数的调用。像下面这样编译和链接这个程序:

linux> gcc -DCOMPILETIME -c mymalloc.c
linux> gcc -I. -o intc int.c mymalloc.o

由于有 -I. 参数,所以会进行打桩,它告诉 C 预处理器在搜索通常的系统目录之前,先在当前目录中查找 malloc.h。注意,mymalloc.c 中的包装函数是使用标准 malloc.h 头文件编译的。

运行这个程序会得到如下的追踪信息:

linux> ./intc
malloc(32)=0x9ee010
free(0x9ee010)

code/link/interpose/int.c

#include <stdio.h>
#include <malloc.h>

int main()
{
    int *p = malloc(32);
    free(p);
    return(0);
}

a)示例程序 int.c

code/link/interpose/malloc.h

#define malloc(size) mymalloc(size)
#define free(ptr) myfree(ptr)

void *mymalloc(size_t size);
void myfree(void *ptr);

b)本地 malloc.h 文件

code/link/interpose/mymalloc.c

#ifdef COMPILETIME
#include <stdio.h>
#include <malloc.h>

/* malloc wrapper function */
void *mymalloc(size_t size)
{
    void *ptr = malloc(size);
    printf("malloc(%d)=%p\n",
           (int)size, ptr);
    return ptr;
}

/* free wrapper function */
void myfree(void *ptr)
{
    free(ptr);
    printf("free(%p)\n", ptr);
}
#endif

c)mymalloc.c 中的包装函数

图 7-20 用 C 预处理器进行编译时打桩