概述
编译过程中叫做未声明符号,未声明的符号可能会使生成的汇编代码里参数压栈和返回值的处理有问题。
如果存在编译告警,这个告警还是针对函数符号,那么gcc编译器会把你的告警符号的输出,变成32位。
链接不到的符号是未定义符号。
如果只是未声明,那么只会告警而不会报错,未定义会直接报错。
例子
用wrap打桩函数当例子,
创建mymalloc.c文件,定义包装函数
包装函数
如果下面的
void *__real_malloc(size_t size);
void __real_free(void *ptr);
这两行被去掉,那么如果只是编译,一定会有编译告警,因为存在未声明符号。
#include <stdio.h>
void *__real_malloc(size_t size);
void __real_free(void *ptr);
//定义malloc 包装函数
void *__wrap_malloc(size_t size)
{
void *ptr = __real_malloc(size); //调用标准库里的malloc
printf("malloc(%d) = %p\n", (int)size, ptr);
return ptr;
}
//定义free 包装函数
void __wrap_free(void *ptr)
{
__real_free(ptr); //调用标准库里的free
printf("free(%p) = %p\n", ptr);
}
建立程序
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *p = malloc(32);
free(p);
return 0;
}
编译链接
gcc -c mymalloc.c
gcc -c myprog.c
gcc -Wl,--wrap,malloc -Wl,--wrap,free -o myprog myprog.o mymalloc.o
或者直接
gcc -Wl,--wrap,malloc -Wl,--wrap,free -o myprog myprog.c mymalloc.c
那么一定会报错,因为你__real_malloc的输出最后会变成32位的,然后你最后去free一个本应该是64位的地址,那一定报错