当前位置: 技术问答>linux和unix
在linux程序里面,知道一个函数地址,改函数是属于某个动态库的,怎么样得到这个动态库的全路径名??
来源: 互联网 发布时间:2015-12-04
本文导语: 如上 另:WIN32可以通过VirtualQuery()和GetModuleFileName()获得。 | gnu的扩展函数dladdr可以做到你所要的,man dladdr可以查到帮助。 另外dl_iterate_phdr可以查到当前进程所装在的所有符号,每查到...
如上
另:WIN32可以通过VirtualQuery()和GetModuleFileName()获得。
另:WIN32可以通过VirtualQuery()和GetModuleFileName()获得。
|
gnu的扩展函数dladdr可以做到你所要的,man dladdr可以查到帮助。
另外dl_iterate_phdr可以查到当前进程所装在的所有符号,每查到一个就会调用你指定的回调函数。
下面的代码示例如何使用dl_iterate_phdr和dladdr
#define _GNU_SOURCE
#include
#include
#include
static int
callback (struct dl_phdr_info *info, size_t size, void *data)
{
int j;
printf ("name=%s (%d segments)n", info->dlpi_name, info->dlpi_phnum);
for (j = 0; j dlpi_phnum; j++) {
void* addr = (void *) (info->dlpi_addr + info->dlpi_phdr[j].p_vaddr);
printf ("tt header %2d: address=%10p", j, addr);
Dl_info dlinfo;
dladdr(addr, &dlinfo);
printf("t %s : %sn", dlinfo.dli_fname, dlinfo.dli_sname);
}
return 0;
}
int
main (int argc, char *argv[])
{
dl_iterate_phdr (callback, NULL);
exit (EXIT_SUCCESS);
}
编译方式:
gcc -o test test.c -ldl
你需要复制一个so文件到当前目录,名字为libtest.so,程序的输出大概是这个样子的:
......
......
name=/lib/libdl.so.2 (9 segments)
header 0: address=0x40039034 /lib/libdl.so.2 : _dl_rtld_di_serinfo
header 1: address=0x4003a9ae /lib/libdl.so.2 : (null)
header 2: address=0x40039000 /lib/libdl.so.2 : __pthread_once
header 3: address=0x4003bed4 /lib/libdl.so.2 : (null)
header 4: address=0x4003beec /lib/libdl.so.2 : (null)
header 5: address=0x40039154 /lib/libdl.so.2 : _dl_rtld_di_serinfo
header 6: address=0x40039174 /lib/libdl.so.2 : _rtld_global
header 7: address=0x40039000 /lib/libdl.so.2 : __pthread_once
header 8: address=0x4003bed4 /lib/libdl.so.2 : (null)
name=/lib/tls/libc.so.6 (11 segments)
header 0: address=0x4003d034 /lib/tls/libc.so.6 : _rtld_global
header 1: address=0x4014a540 /lib/tls/libc.so.6 : (null)
header 2: address=0x4003d000 /lib/tls/libc.so.6 : GCC_3.0
header 3: address=0x401505ec /lib/tls/libc.so.6 : (null)
header 4: address=0x40151d3c /lib/tls/libc.so.6 : (null)
header 5: address=0x4003d194 /lib/tls/libc.so.6 : _rtld_global
header 6: address=0x4003d1b4 /lib/tls/libc.so.6 : _rtld_global
header 7: address=0x401505ec /lib/tls/libc.so.6 : (null)
header 8: address=0x4014a554 /lib/tls/libc.so.6 : (null)
header 9: address=0x4003d000 /lib/tls/libc.so.6 : GCC_3.0
header 10: address=0x401505f4 /lib/tls/libc.so.6 : (null)
name=/lib/ld-linux.so.2 (6 segments)
header 0: address=0x40000000 /lib/ld-linux.so.2 : GLIBC_2.1
header 1: address=0x40016cc0 /lib/ld-linux.so.2 : _rtld_global_ro
header 2: address=0x40016f34 /lib/ld-linux.so.2 : (null)
header 3: address=0x40015abc /lib/ld-linux.so.2 : (null)
header 4: address=0x40000000 /lib/ld-linux.so.2 : GLIBC_2.1
header 5: address=0x40016cc0 /lib/ld-linux.so.2 : _rtld_global_ro
另外dl_iterate_phdr可以查到当前进程所装在的所有符号,每查到一个就会调用你指定的回调函数。
下面的代码示例如何使用dl_iterate_phdr和dladdr
#define _GNU_SOURCE
#include
#include
#include
static int
callback (struct dl_phdr_info *info, size_t size, void *data)
{
int j;
printf ("name=%s (%d segments)n", info->dlpi_name, info->dlpi_phnum);
for (j = 0; j dlpi_phnum; j++) {
void* addr = (void *) (info->dlpi_addr + info->dlpi_phdr[j].p_vaddr);
printf ("tt header %2d: address=%10p", j, addr);
Dl_info dlinfo;
dladdr(addr, &dlinfo);
printf("t %s : %sn", dlinfo.dli_fname, dlinfo.dli_sname);
}
return 0;
}
int
main (int argc, char *argv[])
{
dl_iterate_phdr (callback, NULL);
exit (EXIT_SUCCESS);
}
编译方式:
gcc -o test test.c -ldl
你需要复制一个so文件到当前目录,名字为libtest.so,程序的输出大概是这个样子的:
......
......
name=/lib/libdl.so.2 (9 segments)
header 0: address=0x40039034 /lib/libdl.so.2 : _dl_rtld_di_serinfo
header 1: address=0x4003a9ae /lib/libdl.so.2 : (null)
header 2: address=0x40039000 /lib/libdl.so.2 : __pthread_once
header 3: address=0x4003bed4 /lib/libdl.so.2 : (null)
header 4: address=0x4003beec /lib/libdl.so.2 : (null)
header 5: address=0x40039154 /lib/libdl.so.2 : _dl_rtld_di_serinfo
header 6: address=0x40039174 /lib/libdl.so.2 : _rtld_global
header 7: address=0x40039000 /lib/libdl.so.2 : __pthread_once
header 8: address=0x4003bed4 /lib/libdl.so.2 : (null)
name=/lib/tls/libc.so.6 (11 segments)
header 0: address=0x4003d034 /lib/tls/libc.so.6 : _rtld_global
header 1: address=0x4014a540 /lib/tls/libc.so.6 : (null)
header 2: address=0x4003d000 /lib/tls/libc.so.6 : GCC_3.0
header 3: address=0x401505ec /lib/tls/libc.so.6 : (null)
header 4: address=0x40151d3c /lib/tls/libc.so.6 : (null)
header 5: address=0x4003d194 /lib/tls/libc.so.6 : _rtld_global
header 6: address=0x4003d1b4 /lib/tls/libc.so.6 : _rtld_global
header 7: address=0x401505ec /lib/tls/libc.so.6 : (null)
header 8: address=0x4014a554 /lib/tls/libc.so.6 : (null)
header 9: address=0x4003d000 /lib/tls/libc.so.6 : GCC_3.0
header 10: address=0x401505f4 /lib/tls/libc.so.6 : (null)
name=/lib/ld-linux.so.2 (6 segments)
header 0: address=0x40000000 /lib/ld-linux.so.2 : GLIBC_2.1
header 1: address=0x40016cc0 /lib/ld-linux.so.2 : _rtld_global_ro
header 2: address=0x40016f34 /lib/ld-linux.so.2 : (null)
header 3: address=0x40015abc /lib/ld-linux.so.2 : (null)
header 4: address=0x40000000 /lib/ld-linux.so.2 : GLIBC_2.1
header 5: address=0x40016cc0 /lib/ld-linux.so.2 : _rtld_global_ro