c++动态库多层动态加载的问题

问题描述:
今有第三方库曰xplico,将xplico.c中的main函数改写成xplico_main然后修改makefile,将之由可执行程序改造成动态库libxplico.so
然后编写测试程序test.cpp(与libxplico.so放到同一路径下),其内容如下:

//test.cpp
#include <iostream>
#include <thread>

extern "C"{
	int xplico_main(int, char *[]);
}

int main(int argc, char *argv[])
{
    std::thread t(xplico_main, argc, argv);
    t.join();
    return 0;
}

g++编译之:# g++ test.cpp -o test -L. -lxplico -lpthread -Wl,-rpath=.
执行test:#./test -m -pcap -f /home/cyz/wahaha.pcap
上述操作能够正常运行

然而
今有一可执行程序曰a.out,动态加载(dlopen)的方式调用一个库liblib.so(c++动态库),在lib中使用test.cpp程序中的std::thread两句程序加载xplico。发现程序报错,提示/opt/in-sec/taa/bin/a.out: symbol lookup error: /opt/in-sec/taa/bin/modules/dis_pcapf.so: undefined symbol: ProtName。打印信息提示a.out能够调用xplico_main,但是当需要加载动态库dis_pcapf.so时程序提示前述错误。
遂做如下检查:
0. nm dis_pcapf.so | grep ProtName //提示ProtName未定义
1. ldd liblib.so //libxplico.so已链接
2. 查看运行时库路径是否正确
3. nm libxplico.so | grep ProtName //提示’0000000000012ed7 T ProtName’,表示已定义!
4. 查看xplico源码中ProtName是否被static修饰
上述五步得出的结论是ProtName在dis_pcapf.so中未定义,定义发生在libxplico.so中,乃是全局共享函数。

于是在主程序a.out主程序中直接通过thread调用xplico_main. 此时发现能够正常启动,于是问题变得不可理喻,为何主程序直接调用xplico_main可以,而通过中间库liblib.so却无能为力?
那么是不是liblib.so中链接的libxplico中的符号对主程序a.out是不可见的呢?遂做如下尝试
将主程序编译时链接上libxplico.so, 程序执行依然遇到同样的问题,然后ldd a.out发现a.out未能链接上libxplicos.so. 原因是虽然我在a.out链接阶段指定了链接libxplico.so,但是未真正使用libxplico.so库中的函数,导致链接器智能的跳过了链接libxplico.so
于是在xplico.c中添加一个调试函数

void xplico_print()
{
	printf("测试\n");
}

a.out源文件中添加

extern "C"{
	void xplico_print();
}

重新编译a.out, ldd查看之则libxplico.so被正常链接,然后执行a.out发现问题解决!
那么问题来了,为什么会出现这种可执行程序直接加载没有问题,而dlopen的库中加载会导致这种符号未定义的错误呢?
查看源码看到上述错误提示中dis_pcapf.so和liblib.so一样,也是通过dlopen动态加载的,那么,是不是dlopen加载的库中间再次dlopen加载另一个库会导致二次加载库中的符号对主程序不可见呢?等有时间求证吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值