Linux GCC查漏补缺

本文围绕GCC编译和动态库加载展开。介绍了gcc -Wl选项可替换标准库函数,--start-group和--end-group解决静态包链接问题,还提及GCC默认参数。阐述了加载动态库的优先级,如LD_PRELOAD最高。此外,说明了文本重定向及检查方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、gcc -Wl,--wrap,function

-Wl表示将参数传递给ld链接器,--wrap,function或者--wrap=function,此选项可以替换标准库函数,实现不改变原有库的情况下,使用新实现替换原有库函数。

Example:

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

void* __real_malloc(size_t size); // 只声明不定义__real_malloc
void* __wrap_malloc(size_t size) // 定义__wrap_malloc
{
    printf("__wrap_malloc called, size:%d\n", size); // log输出
    return __real_malloc(size); // 通过__real_malloc调用真正的malloc
}

int main(void)
{
    void* mem=malloc(10);
}

输出:

d:\VScode\.vscode>gcc wrap_test.c -o wrap_test -Wl,--wrap,malloc

d:\VScode\.vscode>wrap_test.exe
__wrap_malloc called, size:16
__wrap_malloc called, size:14
__wrap_malloc called, size:10

2, --start-group和--end-group

编译的时候出现了一个问题,对于静态包(.a)链接的时候,如果出现后面的包依赖前面的包的情况,则会报undefined reference,

例如:

#liba.a引用了libb.a的函数
gcc hello.c -o hello libb.a liba.a
#liba.a无法找到libb.a的引用

这个时候使用--start-group  liba.a libb.a --end-group,链接器会在start和end之间循环查找引用。

gcc hello.c -o hello --start-group  libb.a liba.a --end-group

3,GCC的默认参数

如果不带-c,不带-o,则默认为-o a.out,也就是既编译又链接。编译阶段不检查全局符号是否存在定义。

4.加载动态库的优先级

动态库的搜索路径搜索的先后顺序是:
    编译目标代码时指定的动态库搜索路径
    环境变量LD_LIBRARY_PATH指定的动态库搜索路径
    配置文件/etc/ld.so.conf中指定的动态库搜索路径
    默认的动态库搜索路径/lib
    默认的动态库搜索路径/usr/lib

①,LD_PRELOAD

可以强制加载二进制文件加载环境变量中的库文件,加载的库的符号拥有最高优先级。

LD_PRELOAD=./xxx.so ./yyy.so 

②,LD_LIBRARY_PATH

加载动态库的时候,可以从指定路径加载,加载顺序处于第二优先级,

export LD_LIBRARY_PATH=./

③,编译期间指定路径

gcc -wl,-rpath ./

如果需要打印链接日志,可以运行期间指定LD_DEBUG

LD_DEBUG 可以设置的值有:

  • “files”,显示整个装载过程;
  • “libs”,显示共享库查找过程;
  • “symbols”,显示符号的查找过程;
  • “bindings”,显示动态链接的符号绑定过程;
  • “versions”,显示符号的版本依赖关系;
  • “reloc”,显示重定位信息;
LD_DEBUG=libs ./test

5,编译查看是否有文本重定向

文本重定向就是text relocation,是指符号的地址在程序运行过程中会发生变化,这个常发生在不使用-fPIC编译的动态库中,这样编译的动态库其实每运行一个程序就会多一份拷贝,其实偏离了共享库内存中仅保存一份的初衷,所以现在的共享库编译都会有-fPIC选项,表示编译PIC的代码,PIC表示位置无关代码position independent code,原理就是对于全局变量的引用时从GOT中进行引用,GOT是每个程序创建的时候创建的唯一符号表,用来记录所有的全局符号,动态库从这里引用就可以避免需要动态修改全局符号地址。

gcc testlib.c -o libtestlib.so -shared -z text

-z text可以检查目标文件文本段是否有地址重定向,如果有,则报警告warning:relocation against “helloint” int read-only section .text

例如:

vim testlib.c

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值