Linux dladdr1(): 无法获取匹配文件的绝对路径名

Linux dladdr1(): Unable to get absolute pathname of the matched file

根据手册页 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
 = {dli_fname = 0x7fffffffe5a7 "/home/user/learn/dlerr/a.out", dli_fbase = 0x400000,
  dli_sname = 0x400674 "main2", dli_saddr = 0x4008bd <main2>}
(gdb) p *ei
 = {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)。

So when man page says extra_info gives absolute path

手册页没有这样说。它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 对象有特殊的整体,它们 没有 由链接器加载;即主要可执行文件和(在 non-ancient 版本的 glibc 上)vdso.

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

info parameter gives required path currently but in a complex project we often find relative paths getting printed

加载程序不知道主可执行文件的路径,因此它无法告诉您可执行文件的位置。

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

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