ImportError: lib64libatk-1.0.so.0: undefined symbol: g

ImportError: lib64libatk-1.0.so.0: undefined symbol: g,第1张

error log:

    import cv2
ImportError: /lib64/libatk-1.0.so.0: undefined symbol: g_type_check_instance_is_fundamentally_a

一步步来分析:

  1. 为什么会报这个错误? => 这涉及到执行到import cv2, python是如何来找到cv2所在的路径的?答案是通过PYTHONPATH环境变量。其实我们pip intall库的时候,只是工具在背后帮我们把库放到了PYTHONPATH环境变量里的路径里。参考文章Linux 安装Opencv中的源代码安装。文章指出在手动编译完opencv之后,需要

    $ su mv /usr/local/lib/python2.7/site-packages/cv2.so /usr/lib/python2.7/site-packages
    $ export PYTHONPATH=$PYTHONPATH:/usr/local/lib/python2.7/site-packages
    

    首先把编译出来的cv2.so 拷贝到/usr/lib/python2.7/site-packages目录下,然后把这个路径加到PYTHONPATH环境变量中。

    顺便说一下,举例来说,对于一个特定的python版本/home/utils/Python-3.5.2/bin/python3,在执行的时候import的库通常在:
    a. /home/utils/Python-3.5.2/lib/python3.5下面的 *.py文件
    b. /home/utils/Python-3.5.2/lib/python3.5/site-packages/ 下面的 *.so文件中。

  2. 既然是import cv2的时候出错,那么大概率是cv2这个库的问题,找到cv2库所在的位置 /home/utils/Python-3.5.2/lib/python3.5/site-packages/cv2.cpython-35m-x86_64-linux-gnu.so, 然后:

    $ ldd /home/utils/Python-3.5.2/lib/python3.5/site-packages/cv2.cpython-35m-x86_64-linux-gnu.so | grep libatk
    libatk-1.0.so.0 => /lib64/libatk-1.0.so.0 (0x00007fffc0bd1000)
    

    果然是cv2依赖 /lib64/libatk-1.0.so.0 这个库。

  3. 我们现在遇到的问题是/lib64/libatk-1.0.so.0这个库里面的g_type_check_instance_is_fundamentally_a这个符号undefine, 那么我们可以通过nm命令查看是否是真的undefine:

    $ nm /lib64/libatk-1.0.so.0
    nm: /lib64/libatk-1.0.so.0: no symbols
    

    为什么no symbols?这很奇怪,在stackOverflow上找到了答案:Why nm libc.so reports no symbols?
    答案是需要加参数 --dynamic。

    $ nm /lib64/libatk-1.0.so.0 --dynamic | grep g_type_check_instance_is_fundamentally_a
            U g_type_check_instance_is_fundamentally_a
    

    果然这个symbol是U(undefine)。

  4. 如何解决?公司有另一台机器可以运行cv2,发现最终使用的libatk的版本是libatk-1.0.so.0.3009.1

    $ ll /usr/lib64/libatk-1.0.so.0
    lrwxrwxrwx 1 root root 22 Feb 17  2017 /usr/lib64/libatk-1.0.so.0 -> libatk-1.0.so.0.3009.1
    

    而出错的那台机器的libatk的版本是libatk-1.0.so.0.22209.1, 看起来是系统中libatk的版本太低导致的。所以说只要升级libatk的版本应该就可以了。
    a. 如果系统中有高版本的libatk,只需要通过设置LD_LIBRARY_PATH让python在load cv2.so的时候找到高版本的libatk就可以了。
    b. 但是我没有在系统中找到高版本的libatk,所以解决办法是。。。找Infra的同事来升级版本吧。

    $ ll /lib64/libatk-1.0.so.0
    lrwxrwxrwx 1 root root 23 Nov 21  2017 /lib64/libatk-1.0.so.0 -> libatk-1.0.so.0.22209.1
    
  5. what is stripped?

    $ file /lib64/libatk-1.0.so.0.22209.1
    /lib64/libatk-1.0.so.0.22209.1: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=52d8c2ffbaecdca6fac51cda5395b35e588f546e, stripped
    

    这里stripped的意思是: 为了减小可执行文件的大小,可以用strip工具来除去debug相关的符号信息。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/715776.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-25
下一篇 2022-04-25

发表评论

登录后才能评论

评论列表(0条)

保存