DLINFO - Linux手册页
Linux程序员手册 第3部分
更新日期: 2020-06-09
名称
dlinfo-获取有关动态加载对象的信息
语法
#define _GNU_SOURCE #include <link.h> #include <dlfcn.h> int dlinfo(void *handle, int request, void *info); Link with -ldl.
说明
dlinfo()函数获取有关句柄引用的动态加载对象的信息(通常是通过对dlopen(3)或dlmopen(3)的较早调用获得的)。 request参数指定要返回的信息。 info参数是一个指向缓冲区的指针,该缓冲区用于存储调用返回的信息。此参数的类型取决于请求。
支持以下值进行请求(括号中显示信息的相应类型):
- RTLD_DI_LMID(Lmid_t *)
- 获取在其中加载了句柄的链接映射列表(名称空间)的ID。
- RTLD_DI_LINKMAP(struct link_map **)
- 获取指向对应于句柄的link_map结构的指针。 info参数指向一个指向link_map结构的指针,该结构定义为:
struct link_map { ElfW(Addr) l_addr; /* Difference between the address in the ELF file and the address in memory */ char *l_name; /* Absolute pathname where object was found */ ElfW(Dyn) *l_ld; /* Dynamic section of the shared object */ struct link_map *l_next, *l_prev; /* Chain of loaded objects */ /* Plus additional fields private to the implementation */ };- RTLD_DI_ORIGIN(char *)
- 将对应于句柄的共享库的原点的路径名复制到info指向的位置。
- RTLD_DI_SERINFO(Dl_serinfo *)
- Obtain the library search paths for the shared object referred to by
handle.
The
infoargument is a pointer to a
Dl_serinfothat contains the search paths.
Because the number of search paths may vary,
the size of the structure pointed to by
infocan vary.
The
RTLD_DI_SERINFOSIZErequest described below allows applications to size the buffer suitably.
The caller must perform the following steps:- 1.
- 使用RTLD_DI_SERINFOSIZE请求以后续RTLD_DI_SERINFO请求所需结构的大小(dls_size)填充Dl_serinfo结构。
- 2.
- 分配正确大小(dls_size)的Dl_serinfo缓冲区。
- 3.
- 使用另一个RTLD_DI_SERINFOSIZE请求填充上一步中分配的缓冲区的dls_size和dls_cnt字段。
- 4.
- 使用RTLD_DI_SERINFO获取库搜索路径。
- Dl_serinfo结构定义如下:
typedef struct { size_t dls_size; /* Size in bytes of the whole buffer */ unsigned int dls_cnt; /* Number of elements in 'dls_serpath' */ Dl_serpath dls_serpath[1]; /* Actually longer, 'dls_cnt' elements */ } Dl_serinfo;- 上述结构中的每个dls_serpath元素都是以下形式的结构:
typedef struct { char *dls_name; /* Name of library search path directory */ unsigned int dls_flags; /* Indicates where this directory came from */ } Dl_serpath;- dls_flags字段当前未使用,并且始终包含零。
- RTLD_DI_SERINFOSIZE(Dl_serinfo *)
- 使用适合于分配缓冲区以供后续RTLD_DI_SERINFO请求使用的值,填充info指向的Dl_serinfo结构的dls_size和dls_cnt字段。
- RTLD_DI_TLS_MODID(size_t *, since glibc 2.4)
- 获取此共享对象的TLS(线程本地存储)段的模块ID,如TLS重定位中所使用。如果此对象未定义TLS段,则* info中将置零。
- RTLD_DI_TLS_DATA(void **, since glibc 2.4)
- 获取指向与该共享库的TLS段相对应的调用线程的TLS块的指针。如果此对象未定义PT_TLS段,或者调用线程尚未为其分配块,则将* NULL放置在* info中。
返回值
成功时,dlinfo()返回0。失败时,它返回-1;否则,它返回-1。可以使用dlerror(3)诊断错误原因。
版本
dlinfo()最早出现在glibc 2.3.3中。
属性
有关本节中使用的术语的说明,请参见attribute(7)。
| Interface | Attribute | Value |
| dlinfo() | Thread safety | MT-Safe |
遵循规范
此函数是非标准的GNU扩展。
备注
该函数源自同名的Solaris函数,并且还出现在某些其他系统上。各种实现所支持的请求集仅部分重叠。
示例
下面的程序使用dlopen(3)打开共享库,然后使用RTLD_DI_SERINFOSIZE和RTLD_DI_SERINFO请求获取库的库搜索路径列表。这是运行程序时可能看到的示例:
$ ./a.out /lib64/libm.so.6 dls_serpath[0].dls_name = /lib64 dls_serpath[1].dls_name = /usr/lib64
Program source
#define _GNU_SOURCE
#include <dlfcn.h>
#include <link.h>
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
void *handle;
Dl_serinfo serinfo;
Dl_serinfo *sip;
int j;
if (argc != 2) {
fprintf(stderr, "Usage: %s <libpath>\n", argv[0]);
exit(EXIT_FAILURE);
}
/* Obtain a handle for shared object specified on command line */
handle = dlopen(argv[1], RTLD_NOW);
if (handle == NULL) {
fprintf(stderr, "dlopen() failed: %s\n", dlerror());
exit(EXIT_FAILURE);
}
/* Discover the size of the buffer that we must pass to
RTLD_DI_SERINFO */
if (dlinfo(handle, RTLD_DI_SERINFOSIZE, &serinfo) == -1) {
fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\n", dlerror());
exit(EXIT_FAILURE);
}
/* Allocate the buffer for use with RTLD_DI_SERINFO */
sip = malloc(serinfo.dls_size);
if (sip == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
/* Initialize the aqdls_sizeaq and aqdls_cntaq fields in the newly
allocated buffer */
if (dlinfo(handle, RTLD_DI_SERINFOSIZE, sip) == -1) {
fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\n", dlerror());
exit(EXIT_FAILURE);
}
/* Fetch and print library search list */
if (dlinfo(handle, RTLD_DI_SERINFO, sip) == -1) {
fprintf(stderr, "RTLD_DI_SERINFO failed: %s\n", dlerror());
exit(EXIT_FAILURE);
}
for (j = 0; j < serinfo.dls_cnt; j++)
printf("dls_serpath[%d].dls_name = %s\n",
j, sip->dls_serpath[j].dls_name);
exit(EXIT_SUCCESS);
}
出版信息
这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/。

