【问题标题】:How to know which so the app has linked in run time?如何知道应用程序在运行时链接了哪个?
【发布时间】:2018-10-25 02:48:27
【问题描述】:

背景:

我在 linux 上有以下代码结构,并且在文件夹 correct_sowrong_so 中有两个不同版本的 caculate.c。我想知道app启动时链接了哪个so

caculate.c 构建的libcac.so 将被main.c 使用。

~/tt$ tree
.
├── correct_so
│   ├── caculate.c
│   ├── caculate.h
│   └── libcac.so
├── main
├── main.c
└── wrong_so
    ├── caculate.c
    ├── caculate.h
    └── libcac.so

correct_so/caculate.c:

#include "caculate.h"

int add(int a, int b)
{
    return (a + b);
}

wrong_so/caculate.c:

#include "caculate.h"

int add(int a, int b)
{
    return (a + b) * 2;
}

caculate.h:correct_sowrong_so 相同)

#ifndef _CACULATE_H__INCLUDE_
#define _CACULATE_H__INCLUDE_
int add(int a, int b);
#endif

ma​​in.c:

#include <stdio.h>
#include <unistd.h>
#include "caculate.h"

int main()
{
    int a = 1;
    int b = 2;
    while (1)
    {
        printf("%d + %d = %d\n", a, b, add(a, b));
        sleep(1);
    }
    return 0;
}

我的问题:

我做了以下步骤,详细参考下一个日志:

  • 在 2 个不同的文件夹中编译出 2 个不同的 libcac.socorrect_so & wrong_so
  • 编译出带有libcac.so链接的main应用程序
  • 使用错误的路径wrong_soLD_LIBRARY_PATH,你可以说1 + 2 = 6的结果。现在我可以使用ldd main,显示libcac.so =&gt; wrong_so/libcac.soldd 通过a predefined order 查找内容,例如/lib, /usr/lib, LD_LIBRARY_PATH etc
  • 如果之后export LD_LIBRARY_PATH=correct_so 指向正确的版本,ldd 只会显示指向正确版本的应用程序链接,但实际上当应用程序启动时,它会找到错误的版本,因为设置了错误的LD_LIBRARY_PATH。所以ldd 在这里帮不了我。

总而言之,我怎么知道一个应用程序是否以正确的方式运行,所以当它在运行时,如果没有打印日志?同时假设LD_LIBRARY_PATH在应用运行时会被其他人更改,甚至可能在系统中没有历史记录。

那么,我可以告诉其他人:哦,系统中有两个版本的库,你只是运行带有问题版本的应用程序,所以应用程序肯定存在运行时问题。

我的实验可能会显示我的问题:

~/tt$ cd correct_so/
~/tt/correct_so$ ls
caculate.c  caculate.h  libcac.so
~/tt/correct_so$ gcc -shared -fPIC caculate.c -o libcac.so
~/tt/correct_so$ cd ..
~/tt$ cd wrong_so/
~/tt/wrong_so$ gcc -shared -fPIC caculate.c -o libcac.so
~/tt/wrong_so$ cd ..
~/tt$ gcc main.c -o main -I correct_so -L correct_so -lcac
~/tt$ ldd main
        linux-vdso.so.1 =>  (0x00007fffd3dfe000)
        libcac.so => correct_so/libcac.so (0x00007f1a70b7c000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1a7079f000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f1a70d80000)
~/tt$ export LD_LIBRARY_PATH=wrong_so && ./main
1 + 2 = 6
1 + 2 = 6
1 + 2 = 6
^Z
[1]+  Stopped                 ./main
~/tt$ ldd main
        linux-vdso.so.1 =>  (0x00007fff1abd9000)
        libcac.so => wrong_so/libcac.so (0x00007fdb5523c000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdb54e5f000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fdb55440000)
~/tt$ export LD_LIBRARY_PATH=correct_so
~/tt$ ldd main
        linux-vdso.so.1 =>  (0x00007fffa11fe000)
        libcac.so => correct_so/libcac.so (0x00007ffeda6b6000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f82f80bc000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f82f849b000)
~/tt$ fg
./main
1 + 2 = 6
^C

【问题讨论】:

  • 嗨,您有没有提议将python-3.6python-3.7 作为python-3.x 的同义词?现在有a meta discussion related to it,特别是Martijn Pieters♦ 评论。
  • @Cœur,我可以删除同义词,谢谢。

标签: c linux shared-libraries ldd


【解决方案1】:
ps -ef | grep main // find your process ID
lsof -p ${pid}
here is my output
main    6839 scliang  cwd    DIR   8,17     4096 226363625 /home/scliang/so
main    6839 scliang  rtd    DIR    8,2     4096        96 /
main    6839 scliang  txt    REG   8,17     8528 226363626 /home/scliang/so/main
main    6839 scliang  mem    REG    8,2  2173512      2139 /usr/lib64/libc-2.17.so
main    6839 scliang  mem    REG   8,17     7864 226493228 /home/scliang/so/wrong_so/libcac.so
main    6839 scliang  mem    REG    8,2   164240      2132 /usr/lib64/ld-2.17.so
main    6839 scliang    0u   CHR  136,0      0t0         3 /dev/pts/0
main    6839 scliang    1u   CHR  136,0      0t0         3 /dev/pts/0
main    6839 scliang    2u   CHR  136,0      0t0         3 /dev/pts/0

【讨论】:

  • 如果 ldd 显示正确的依赖关系,则可能不会发生这种情况,然后运行时链接器将从同一路径加载,而不是从先前定义的路径中选择库。
猜你喜欢
  • 2012-06-18
  • 1970-01-01
  • 1970-01-01
  • 2011-04-21
  • 2015-07-10
  • 2020-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多