交叉编译后,应用程序无法在QNX系统上执行的问题的排查记录

文章讲述了同事在QNX系统上编译vsomeip示例时遇到的问题,由于编译通过但运行失败,发现是由于编译环境与运行环境的libstdc++和c++库不一致导致的,条件变量在运行环境中缺失。这强调了在进行跨平台开发时环境一致性检查的重要性。
摘要由CSDN通过智能技术生成

前端时间一位同事遇到一个问题,当时和他一起排查,感觉这个问题挺有意思,在这里记录一下。

背景:

这个同事因为项目需要,需要编译QNX系统上可用的vsomeip库,对于vsomeip库,搞车载软件的应该都知道,这个应该是市面上为数不多的开源的someip通信库。使用过QNX系统的朋友应该都知道,编译这玩意的上的应用程序,都需要交叉编译的。搞Linux嵌入式开发的朋友,应该对交叉编译深有体会,自己写的代码还好,一旦遇到移植开源库的时候,就各种的头疼了。之前为了移植jemalloc到qnx系统上,真是头疼,不仅需要将automake修改cmake(个人习惯,cmake对于交叉编译确实好用),还要去解决Linux系统有而qnx系统没有的一些函数接口问题,老头疼了。

问题:

同事在编译vsomeip的example的时候,编译是通过了,但是不能在QNX系统上运行。一开始还以为是编译的vsomeip库有问题,后来同时单独写了一个类似的demo,交叉编译也是通过了,在qnx系统上也是不能运行,无论是虚拟机还是板子上,都无法运行。代码如下:

#include<iostream>
#include<thread>
#include <mutex>
#include <condition variable>
#include <chrono>

std::mutex mtx;
std::condition variable cv;
bool ready = false;

void do work(){
    //模拟工作耗时
   std::this thread::sleep for(std::chrono::seconds(2));
   std::lock guard<std::mutex>lock(mtx);
   ready = true;
//通知一个等待的线程
   cv.notify_one();
}

int main(){
    std::thread worker(do work);
    std::unique lock<std::mutex> lock(mtx);
    while (!ready){
     if(cv,wait for(lock, std::chrono::seconds(1))== std::cv status::timeout) 
     {
          std::cout<<"still waiting after 1 second..."<<std::endl;
     }
     else
     {
        std::cout'<<"Work completed!"<<std::endl,break;//条件满足,退出循环
      }

     worker.join();
     return 0;
}

很简单的一种多线程启动与线程同步的方式。使用QNX的编译器 qcc也是编译通过了。

但是在qnx系统上运行该程序的是就出现问题了

出现的问题是:在libstd++库中没有找到条件变量(condition_variable)对应的符号,或者可以理解为没有在C++库中没有找到条件变量的实现,这一下子有点郁闷了,这不应该啊,不带这么玩了啊,这玩意不是stl携带的吗,怎么就没了尼。一下整不会了。

问题分析与解决

郁闷归郁闷,问题还得解决,工作还得继续干。按照我的理解,如果在编译的环境,能够编译通过,那么理论上编译环境中的libstdc++.so中是携带添加变量符号与实现的(当然有的系统会将libstdc++.so中的服务该剥离了,但是比较少。),所以我当时还以是不是供应商给的QNX系统和编译器版本不对应的。然后让同事通过ldd 命令查看该应用程序依赖的c++库,拷贝到目标系统上。

设置库的环境变量,然后再次运行之前编译的应用程序。

从截图上看,库是已经使用了我们考过去的库了,但是程序依然无法正常运行。不过当前错误不同与前一个错误,这个错误是libc++找不到pthread_cond_clockwait。看到这个第一反应是应用程序没有link libpthread.so。后来一想。md,QNX上没有这玩意,如果有这玩意,编译的时候应该是编译失败的,又是一阵郁闷,到底是哪出错了呢。不过,从这结果上看,系统上库与提供的编译工具链的环境应该存在不一致的情况,至少stdc++和c++这个库是不一致的。这个可以从显示的错误上可以看出来。

现在的情况是:

编译环境:能够编译出应用成,也就是说,编译环境中能够提供应用程序运行所需要的所有代码指令以及相应的库。

运行环境:在运行环境中,无法允许编译环境中编译出来的应用程序。

前面已经证明了运行环境中所需要的库可能存在问题,那么推测,其他库也就有可能出问题或者不一致,因此我和他说,实在不行,咱就把libm.so.libc.so这两库也考过去试试,理论上来说这俩库不应该出现这个问题。

然后奇迹出现了

于是同事喊出了经典的口头禅。哈哈

总结:

这个问题给我的一个提示是:交叉编译中,在编译环境中如果通过,而在运行环境中无法运行,说明:编译环境与运行环境存在不一致的情况,这个就需要验证环境的一致性或者

  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值