Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Linux dladdr1():无法获取匹配文件的绝对路径名_C_Linux_Gnu_Glibc - Fatal编程技术网

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

C Linux dladdr1():无法获取匹配文件的绝对路径名,c,linux,gnu,glibc,C,Linux,Gnu,Glibc,根据手册页,额外信息包含绝对路径名。我不确定是否正确理解了手册页,但无法获得文件的绝对路径名。以下是我尝试过的: 源代码: #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; //

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

源代码:

#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;
}
结果:

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)
24 printf(“name=%s[%s]\n”,i.dli\u sname,ei->l\u name);
(gdb)
name=main2[]
27返回1;
(gdb)p i
$1={dli_fname=0x7fffffe5a7”/home/user/learn/dlerr/a.out“,dli_fbase=0x400000,
dli_sname=0x400674“main2”,dli_saddr=0x4008bd}
(gdb)p*ei
$2={l_addr=0,l_name=0x7ffff7ffe6d8',l_ld=0x600e08,l_next=0x7ffff7ffe6e0,
l_prev=0x0}
(gdb)
注意:info参数给出了当前所需的路径,但在一个复杂的项目中,我们经常会发现在调试时打印相对路径(不尝试此API)。所以,当手册页上说“额外信息”给出了绝对路径时,我想依靠它。同样,*info和*extra_info不是互斥的wrt,至少按照手册页返回路径名。(gcc版本为4.8.x)

所以,当手册页上说“额外信息”时,会给出绝对路径

手册页上没有这么说。它:

RTLD\u DL\u链接映射
获取指向匹配文件的链接映射的指针。这个
extra_info参数指向指向链接映射的指针
结构(即结构链接图**),定义如下:
... 从link.h复制结构链接映射。。。
手册页是正确的:您会得到一个指向
link\u map
的指针。链接.h也是正确的,但不完整

正在发生的事情是,在
link\u map
条目列表中,存在链接器未加载的
ELF
对象的特殊实体;即主可执行文件和(在非古代版本的glibc上)的

由于这些条目是由内核加载的,
链接映射
不包含它们的完整路径名

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

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

通常,您可以通过专门处理
链接映射
列表中的第一个条目来找到该路径:例如,使用
readlink(/proc/self/exe)

这在一些特殊情况下会失败:当
/proc
未装入时,或者在代码开始执行之前主可执行文件已被删除时,但这些情况非常罕见

所以,当手册页上说“额外信息”时,会给出绝对路径

手册页上没有这么说。它:

RTLD\u DL\u链接映射
获取指向匹配文件的链接映射的指针。这个
extra_info参数指向指向链接映射的指针
结构(即结构链接图**),定义如下:
... 从link.h复制结构链接映射。。。
手册页是正确的:您会得到一个指向
link\u map
的指针。链接.h也是正确的,但不完整

正在发生的事情是,在
link\u map
条目列表中,存在链接器未加载的
ELF
对象的特殊实体;即主可执行文件和(在非古代版本的glibc上)的

由于这些条目是由内核加载的,
链接映射
不包含它们的完整路径名

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

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

通常,您可以通过专门处理
链接映射
列表中的第一个条目来找到该路径:例如,使用
readlink(/proc/self/exe)


在某些情况下,这种方法会失败:当未装入
/proc
时,或者当主可执行文件在代码开始执行之前已被删除时,但这些情况非常罕见。

手册页对dli\u fname显示“包含地址的共享对象的路径名”,对l\u name显示“找到对象的绝对路径名”。由于我在编译时搜索绝对路径名,因此-g3 compile标志存储了大量信息,正如我在手册中提到的那样,似乎“并不相互排斥”(但看起来它们相互排斥),我将其作为编译时绝对路径名(很棒的特性)我在任何地方都没见过。>手册上说。。。“找到对象的绝对路径名”用于l_名称,但没有这样说。该文本引用自
link.h
。手册页上显示dli_fname的“包含地址的共享对象的路径名”和“找到对象的绝对路径名”“为了你的名字。由于我在编译时搜索绝对路径名,因此-g3 compile标志存储了大量信息,正如我在手册中提到的那样,似乎“并不相互排斥”(但看起来它们相互排斥),我将其作为编译时绝对路径名(很棒的特性)我在任何地方都没见过。>手册上说。。。“找到对象的绝对路径名”作为l_名称——它没有这样说。该文本引用自
link.h
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)
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 ...