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
未安装时,或者当主要可执行文件在您的代码开始执行之前已被删除时,但这些情况非常罕见。
根据手册页 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
未安装时,或者当主要可执行文件在您的代码开始执行之前已被删除时,但这些情况非常罕见。