dladdr 获取不到绝对路径
时间: 2024-05-09 19:08:31 浏览: 98
`dladdr()` 函数可以用来获取一个函数或变量的地址所在的动态链接库的信息。但是,它只能获取到动态链接库相对于进程加载地址的偏移量,并不能获取到绝对路径。
如果你想要获取动态链接库的绝对路径,可以考虑使用 `/proc` 文件系统。在 Linux 中,每个进程都有一个 `/proc` 目录,其中包含了该进程的详细信息,包括进程加载的动态链接库信息。你可以通过读取 `/proc/<pid>/maps` 来获取进程加载的动态链接库的地址范围和文件路径等信息。
具体来说,你可以使用 `getpid()` 函数获取当前进程的 PID,然后构造出 `/proc/<pid>/maps` 文件的路径。接着,你可以使用标准的文件读取函数(如 `fopen()`、`fread()` 等)来读取该文件,并解析其中的内容以获取动态链接库的绝对路径。
相关问题
linux环境 调用dladdr函数为什么获取不到绝对路径
`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` 函数获取库的绝对路径。
linux环境 dladdr获取到的是相对路径
是的,`dladdr()` 函数获取的是共享库的相对路径,而不是绝对路径。如果你想要获取绝对路径,可以使用 `realpath()` 函数将相对路径转换为绝对路径,例如:
```c
#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>
int main() {
void *handle = dlopen("libtest.so", RTLD_NOW);
if (handle == NULL) {
printf("dlopen error: %s\n", dlerror());
return 1;
}
Dl_info info;
if (dladdr(handle, &info) == 0) {
printf("dladdr error: %s\n", dlerror());
return 1;
}
char *abs_path = realpath(info.dli_fname, NULL);
if (abs_path == NULL) {
printf("realpath error\n");
return 1;
}
printf("The absolute path of the shared library is %s\n", abs_path);
dlclose(handle);
return 0;
}
```
这段代码打印出来的结果会是类似于 `/home/user/libtest.so` 的绝对路径。
阅读全文