ARM平台动态库加载顺序不同引起的程序崩溃

最近项目在适配飞腾国产化平台(ARM架构),消息队列动态库(zeromq)在一些程序上表现很好,在另一些程序上一定会导致crash。面对这种场景我的内心也是崩溃的。问题还是的解决啊!那么就得分析原因到底出在哪里?按之前的经验可能有以下原因:

1. zmq动态库代码的bug,包括自己封装的消息队列API库(libbmqapi.so)

2. zmq动态库和其他库兼容的问题(之前就遇到过mysql和openssl兼容的问题)

3. 编译引起的,比如说Makefile里面库的链接位置等。

通过gdb trace发现

item_nbr变成了很大的值,从而导致访问越界引起crash。因此我猜想是不是内存被破坏了。同时这些库函数只在部分程序中表现出问题,因此我首先排除了原因1。原因2就得写测试程序来说明了,而且测试程序必须足够简单,只连接zmq相关的库。经过几分钟的ctrl+C和ctrl+V,测试程序出来了。到平台上一运行。Duang!!!crash了。我的内心又崩溃了,这好像又把矛头指向了原因1。

喝口水,看会股票,尼玛,内心更崩溃,2022/03/15大盘跌4.95%。。。。尽管内心是焦虑的、崩溃的,精神状态是悲哀的。工作还得继续啊,要不然股票亏得死,工作做不好有失业的风险就越来越大。

言归正传,由于我的测试程序是ctrl+C和ctrl+V不崩溃的程序来的,我就回退Makefile看是不是编译引起的。当我把当前repo下common/tool.cpp编译进来后,居然不crash了,需要说明的是这个tool.cpp不需要引入其他第三方动态库,只是一些公共的字符串处理函数之类的。纳尼!!跟这东西有关系, 这不科学啊!!!突然我想起来,执行了一下ldd看他们到底有什么差异,是不是加了tool.cpp引入了什么新的库?

 对比发现,所有的库是都是一样的,唯一有区别的是加载顺序不一样。上图左边的一定好使,右边的一定crash。从上图可以看出,正常的是先加载libstdc++,不正常的是先加载libc,我又用strace了一下,看起来确实加载stdc++后和加载libc那一段有点区别。我又进一步想到这个zmq的核心是c++写的。难道只有stdc++在前才能正常运行?然后我对正常运行的程序和不正常运行的程序都ldd看了看,结果表明似乎stdc++先装载就可以!那要怎样才能调整动态库的加载顺序呢,我朝着这个方向去摸索了。首先想到的是修改Makefile的连接顺序,改来改去,好像并不是按连接顺序来的。然后又百度,无果。我鼓起勇气向前同事(principal engineer)请教,然后他提供了一个方法(如果想手工修改load顺序,大概这样 你的主程序把main改成__main__,编成so, 然后另外一个lanch程序里面dl_open 加载各个so,最后load主程序so,然后找到__main__函数,然后call),看了半天我表示不会!毕竟是前同事了,我不好意思要别人手把手教。我放弃了这条路,又开始各种百度,还是没有结果,很快两天过去了,问题依然在。

又跟各种高手讨论,他提醒了一句是不是加载的顺序不同导致动态绑定的函数不同?嗯!值得往这方面思考一下,那我把zmq静态库引入到libbmqapi.so呢。哎哟!我的测试程序引用libbmqapi.so就不再crash了,即使不再编译common/tool.cpp。似乎光明就在前方,冲冲!!!我把crash的程序Makefile改一下,只连接这个包含静态库的libbmqapi.so。见证奇迹的时刻到了!哦豁!还是crash!因为这些程序加载的动态库蛮多的。我再次陷入了无解崩溃没有方向的状态。。。。加上今天上午大A还在跌,差一点3000都没保住,心情也是极度苦闷。

下午突然灵光一现,看到crash的程序都引用着某个公共的so库,暂且叫它A库,这个库加载很靠前(在libc.so.6前),A库又依赖libbmqapi.so。如果把libbmqapi变成静态库引入A库会是怎样,那么是不是相当于提升了zmq的加载顺序呢?经过这番骚操作,奇迹真的出现了,不再crash了!

那么结论到底是什么呢?

我现在都不完全确定,到底是编成静态库就解决了问题,还是间接提升了加载顺序解决的问题。但是通过我的测试程序说明,至少动态库的加载顺序是可能会影响程序运行的,特别是arm平台上。比如说mmap指定一个具体的地址,但是加载顺序不一样可能导致这个地址无法map?比如说加载顺序不同导致动态绑定的函数不同?

------------------------------------------------------------------------------------------------------------------------------

假如有高手看到这篇博文,遇到了类似的问题,知道具体是啥原因,欢迎留言指正。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值