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 ...