【问题标题】:Linux dladdr1(): Unable to get absolute pathname of the matched fileLinux dladdr1():无法获取匹配文件的绝对路径名
【发布时间】:2017-01-12 07:41:19
【问题描述】:

根据手册页 extra_info 包含绝对路径名。我不确定我是否正确理解了手册页,但我无法获得文件的绝对路径名。这是我尝试过的:

源代码:

#define _GNU_SOURCE
#include <dlfcn.h>
#include <link.h>

#include <stdio.h>

int  main2(int i)
{
        return 2+i;
}

int main(void)
{
    Dl_info i={0};
    int r;
//  struct link_map ei_={0}, *ei=&ei_;
    struct link_map *ei=0;
    void *ptr = (void*)main2;

    r = dladdr1(ptr, &i, (void**)&ei, RTLD_DL_LINKMAP);

    if(r)
    {
        printf("name = %s [%s]\n", i.dli_sname, ei->l_name);
    }

    return 1;
}

这样编译:

gcc -g3 -rdynamic -ldl dlerr.c

结果:

name = main2 []   

gdb 会话:

24              printf("name = %s [%s]\n", i.dli_sname, ei->l_name);
(gdb)
name = main2 []
27          return 1;
(gdb) p i
$1 = {dli_fname = 0x7fffffffe5a7 "/home/user/learn/dlerr/a.out", dli_fbase = 0x400000,
  dli_sname = 0x400674 "main2", dli_saddr = 0x4008bd <main2>}
(gdb) p *ei
$2 = {l_addr = 0, l_name = 0x7ffff7ffe6d8 "", l_ld = 0x600e08, l_next = 0x7ffff7ffe6e0,
  l_prev = 0x0}
(gdb)

注意:info 参数目前给出了所需的路径,但在复杂的项目中,我们经常发现在调试时会打印相对路径(未尝试过此 API)。所以当手册页说 extra_info 给出绝对路径时,我想依赖它。同样, *info 和 *extra_info 至少按照手册页返回路径名不是互斥的。 (gcc 版本是 4.8.x)。

【问题讨论】:

    标签: c linux gnu glibc


    【解决方案1】:

    所以当手册页说 extra_info 给出绝对路径时

    手册页没有这么说。它says

    RTLD_DL_LINKMAP
              Obtain a pointer to the link map for the matched file.  The
              extra_info argument points to a pointer to a link_map
              structure (i.e., struct link_map **), defined in <link.h> as:
      ... copy of struct link_map from link.h ...
    

    手册页是正确的:你得到了一个指向link_map 的指针。 link.h 正确,但不完整。

    发生的情况是,在link_map 条目列表中,存在链接器加载的ELF 对象的特殊整体;即主要可执行文件和(在 glibc 的非古代版本上)vdso

    由于这些条目是由内核加载的,link_map 不包含它们的完整路径名。

    info 参数目前给出了所需的路径,但在复杂的项目中,我们经常会发现相对路径被打印出来

    加载器不知道主可执行文件的路径,因此它无法告诉您该可执行文件在哪里。

    通常您可以通过特别处理 link_map 列表中的第一个条目来找到该路径:例如使用readlink(/proc/self/exe)

    这在极端情况下会失败:当 /proc 未安装时,或者在您的代码开始执行之前已删除主可执行文件时,但这些情况很少见。

    【讨论】:

    • 手册页显示 dli_fname 为“包含地址的共享对象的路径名”,l_name 为“找到对象的绝对路径名”。由于我在编译时搜索绝对路径名,因为 -g3 编译标志存储了大量信息,并且正如我在手册中提到的那样,似乎“不是互斥的”(但看起来它们是互斥的),我已经接受了作为我从未在任何地方见过的编译时绝对路径名(很棒的功能)。
    • > 手册页说 ... 找到对象的绝对路径名" for l_name -- 它没有这么说。该文本被引用 来自link.h
    猜你喜欢
    • 1970-01-01
    • 2013-11-17
    • 2014-10-22
    • 2012-04-24
    • 2010-09-18
    • 1970-01-01
    相关资源
    最近更新 更多