• 写动态库时遇到了symbol lookup error问题


    之前写TLPI上的代码一直是手动进行错误处理,感觉代码冗余量很大,最后还是决定使用书上的tlph_hdr.h,顺便回顾下动态库的创建/使用。

    参考很久之前的一篇博客 linux上静态库和动态库的编译和使用

    但是感觉这篇博客写了后我一直没真正用过动态库,于是花了些时间复习下,结果倒好,一直出问题。

    xyz@ubuntu:~/lib$ ls
    a.out  f.c  g.c  h.c  libutil.so  main.c  util.h

    f.c g.c h.c分别是3个函数f()、g()、h()的定义,util.h是这3个函数的声明,main.c包含了util.h,并在main()函数中调用了这3个函数。

    a.out则是成功生成的程序,生成过程如下

    xyz@ubuntu:~/lib$ gcc f.c g.c h.c -fpic -shared -o libutil.so
    xyz@ubuntu:~/lib$ gcc main.c -L. -lutil

    第一步编译了3份包含函数具体实现的源文件,第二步编译了主程序。

    其中-L.将当前目录设为动态库查找位置,-lutil代表查找的动态库为libutil.so,这只是语法糖,这句命令用libutil.so替换-lutil也可以。

    最后运行a.out时报错

    ./a.out: symbol lookup error: ./a.out: undefined symbol: f

    自己瞎折腾半天不知道原因,起初怀疑动态库生成错误,没有包含3个函数,但是命令并没错。最后还是动用搜索引擎,试着用ldd(1)来查看程序依赖库(ldd的使用在TLPI的第3章 3.3中查找glibc共享库的位置时也使用过)

    xyz@ubuntu:~/lib$ ldd a.out 
        linux-vdso.so.1 =>  (0x00007fff509eb000)
        libutil.so => /usr/lib/x86_64-linux-gnu/libutil.so (0x00007f1a9e581000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1a9e1b7000)
        /lib64/ld-linux-x86-64.so.2 (0x000055fcfc069000)

    原因出来了,系统自带了一个libutil.so,我自定义的动态库和它重名了,由于动态库是优先查找系统路径(再其次是-L后面的路径,在这里是当前目录),系统自带的libutil.so自然不会有f() g() h()这三个函数,因此f()被认为是未定义的符号,即找不到函数f()的具体定义。

    只要改个名字就行了,然后就遇到了下面错误

    xyz@ubuntu:~/lib$ gcc f.c g.c h.c -fpic -shared -o libfgh.so
    xyz@ubuntu:~/lib$ gcc main.c -L. -lfgh
    xyz@ubuntu:~/lib$ ./a.out 
    ./a.out: error while loading shared libraries: libfgh.so: cannot open shared object file: No such file or directory

    最好的解决方式还是把动态库目录加到环境变量里,而不是把动态库随便扔个系统目录。

    xyz@ubuntu:~/lib$ export LD_LIBRARY_PATH=$(pwd)
    xyz@ubuntu:~/lib$ echo $LD_LIBRARY_PATH 
    /home/xyz/lib
    xyz@ubuntu:~/lib$ ./a.out 
    f()
    g()
    h()

    运行成功,然而这个环境变量重启后就没了,所以需要把它添加到在~/.bashrc末尾,此时就需要把当前目录用绝对路径表示了

    export LD_LIBRARY_PATH=/home/xyz/lib 

    这样系统重启之后便仍可运行a.out,如果需要通知系统.bashrc文件已更新,可用命令source ~/.bashrc

  • 相关阅读:
    用jQuery写的一个简单的弹出窗口(IE7\IE8\FF3)
    live write test
    sql2
    查询所有表索引
    java初学问题记录(2012.02.092012.02.16)
    SQL
    centso7网卡bond
    vmware模板
    Dockerfile参考
    Docker简单介绍
  • 原文地址:https://www.cnblogs.com/Harley-Quinn/p/7079995.html
Copyright © 2020-2023  润新知