linux环境 调用dladdr函数为什么获取不到绝对路径
时间: 2024-01-03 18:05:32 浏览: 184
`dladdr` 函数可以用于获取动态链接库的相关信息,包括库的名称、基址和符号地址等。但是它不能直接获取动态链接库的绝对路径,因为在 Linux 系统中,动态链接库的加载路径可能是多个,而且在加载时可能会被重定位到其他位置。
如果你需要获取动态链接库的绝对路径,可以尝试使用 `dl_iterate_phdr` 函数来遍历所有加载的动态链接库,然后判断哪个库的基址等于给定的符号地址,然后获取该库的绝对路径。
这里是一个示例代码:
```c
#include <dlfcn.h>
#include <link.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void *get_func_addr(const char *lib_path, const char *func_name) {
void *lib_handle = dlopen(lib_path, RTLD_LAZY);
if (!lib_handle) {
fprintf(stderr, "Failed to open %s: %s\n", lib_path, dlerror());
return NULL;
}
void *func_addr = dlsym(lib_handle, func_name);
if (!func_addr) {
fprintf(stderr, "Failed to find symbol %s in %s: %s\n", func_name, lib_path, dlerror());
dlclose(lib_handle);
return NULL;
}
struct dl_phdr_info info;
memset(&info, 0, sizeof(info));
info.dlpi_name = lib_path;
dl_iterate_phdr(
[](struct dl_phdr_info *info, size_t size, void *data) {
if (info->dlpi_addr == reinterpret_cast<uintptr_t>(data)) {
char *path = realpath(info->dlpi_name, NULL);
if (path) {
printf("Library %s path: %s\n", info->dlpi_name, path);
free(path);
}
return 1;
}
return 0;
},
func_addr);
dlclose(lib_handle);
return func_addr;
}
int main() {
void (*hello)() = reinterpret_cast<decltype(hello)>(get_func_addr("./libhello.so", "hello"));
if (hello) {
hello();
}
return 0;
}
```
这个示例代码可以在加载 `libhello.so` 库时输出它的绝对路径。注意,在遍历 `dl_phdr_info` 结构体时,我们需要判断 `info->dlpi_addr` 是否等于 `hello` 函数的地址,以确定哪个库包含了该函数。同时,我们还调用了 `realpath` 函数获取库的绝对路径。
阅读全文