【问题标题】:Find location of loaded shared library, from in that shared library?从该共享库中查找已加载共享库的位置?
【发布时间】:2019-07-25 19:54:30
【问题描述】:

从共享库中的一个函数,在一个正在运行的进程(用 C 语言编写)中,我如何发现该共享库是从哪里加载的?

我找到的所有答案都涉及在命令行中使用诸如ldd 之类的东西,或者通过查看/proc/self/maps

在 Win32 上,我只使用 GetModuleFileName(GetModuleHandle("foo.dll"), szPath, COUNTOF(szPath))。 Linux 等价物是什么?

额外问题:我在 OS X 中需要相同的信息。

【问题讨论】:

标签: c linux shared-libraries


【解决方案1】:

您可以使用 dl_iterate_phdr 来迭代所有加载的库及其段(类似的功能可用于 OSX,请参阅例如 this question)。但是大多数项目只是解析/proc/self/maps

请注意,映射可能会动态变化(如果库是通过 dlopen 加载的),因此在启动时读取它们可能还不够。

【讨论】:

    【解决方案2】:

    实现此目的的一种方法是使用 dladdr:

    共享对象的代码:

    $ cat so.c 
    #include <stdio.h>
    #include <dlfcn.h>
    void test_so_func()
    {
     Dl_info info;
     if (dladdr(test_so_func, &info))
     {
        printf("Loaded from path = %s\n", info.dli_fname);
     }
     printf("hello\n");
    }
    

    主执行代码:

    $ cat test.c
    void test_so_func();
    
    int main() {
      test_so_func();
      return 0;
    }
    

    生成文件:

    $ cat Makefile 
    test: test.o libso.so
        gcc test.o -o $@ -Wl,-L.,-lso,-rpath,'$$ORIGIN'
    
    clean:
        -rm -f libso.so test.o test
    
    libso.so: so.c
        gcc -D_GNU_SOURCE=1 -fPIC -shared $< -o $@ -lc -ldl
    
    test.o: test.c
        gcc -fPIC -c $< -o $@
    

    让我们编译吧!

    $ make
    gcc -fPIC -c test.c -o test.o
    gcc -D_GNU_SOURCE=1 -fPIC -shared so.c -o libso.so -lc -ldl
    gcc test.o -o test -Wl,-L.,-lso,-rpath,'$ORIGIN'
    

    测试这个二进制文件。

    $ ./test 
    Loaded from path = /spare/scratch/1564054710/libso.so
    hello
    

    验证 libso.so 确实说的是真话。

    $ ldd ./test
        linux-vdso.so.1 =>  (0x00007ffdf55d5000)
        libso.so => /spare/scratch/1564054710/./libso.so (0x00007fbcc4602000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbcc4238000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fbcc4034000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fbcc4804000)
    

    这个答案的功劳归于https://github.com/mingwandroid

    【讨论】:

    猜你喜欢
    • 2019-02-10
    • 2019-04-17
    • 1970-01-01
    • 2014-03-04
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 1970-01-01
    相关资源
    最近更新 更多