Linux高级--2.3 携程的hook实现及dlsym函数

背景知识:(排除static 情况)

一个进程中可以有相同的命名吗? -- 不能

两个进程之间可以有相同的命名吗?--可以

一个进程和另一个静态库可以有相同的命名吗?--不能

一个进程和另一个动态库之间可以有相同的命名吗?--可以

在考虑 进程静态库动态库 中的函数与变量命名是否可以相同时,需要从作用域、链接阶段、加载机制等角度进行分析。以下分别讨论静态库和动态库的情况:


1. 进程与静态库之间的函数或变量命名是否可以相同?

可以,但需注意链接时的冲突。

原因:
  • 静态库的性质:静态库(.a 文件)在编译阶段被链接器整合到可执行文件中,其代码最终成为可执行文件的一部分。因此,静态库中的函数或变量在链接时会与进程(可执行文件)的代码共享同一命名空间。
  • 冲突情况
    • 如果进程代码中定义了与静态库相同的函数或变量名,链接器会发生符号重定义错误,除非通过弱符号等机制处理。
    • 如果名称不同,则不会产生冲突。
示例:
  1. 正常情况

    • 静态库 libexample.a 中定义了函数 void foo()
    • 可执行文件中没有定义 foo(),则链接器会将 foo() 从静态库中包含到可执行文件中。
  2. 冲突情况

    • 如果静态库和可执行文件都定义了 void foo(),链接器会报错:
      duplicate symbol: foo
      
  3. 解决方法

    • 避免冲突:确保静态库和可执行文件的全局命名空间中没有重复定义。
    • 使用弱符号:通过 __attribute__((weak)) 标记静态库的符号为弱符号,让进程中的定义优先。

2. 进程与动态库之间的函数或变量命名是否可以相同?

可以,但需注意运行时的符号解析规则。

原因:
  • 动态库的性质:动态库(.so 文件)中的代码在运行时由动态链接器加载到进程中。如果动态库与可执行文件存在同名函数或变量,符号解析规则决定了哪个定义会被使用。
符号解析规则:
  1. 默认规则

    • 可执行文件中的符号优先于动态库中的符号。
    • 如果可执行文件没有定义某个符号,则动态库中的定义会被使用。
  2. 显式控制规则

    • 使用 --export-dynamic 编译选项,可以让可执行文件中的符号在动态链接器中被导出,从而覆盖动态库中的同名符号。
    • 使用动态库加载函数(如 dlopen()dlsym())时,可以显式指定使用动态库中的符号。
示例:
  1. 正常情况

    • 动态库 libexample.so 中定义了函数 void bar()
    • 可执行文件中没有定义 bar(),则运行时会使用动态库中的 bar()
  2. 冲突情况

    • 如果动态库和可执行文件都定义了 void bar(),运行时会优先使用可执行文件中的 bar(),即使动态库的 bar() 被链接到进程中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值