1)。直接打印函数地址:
printf("strerror=%p, strerror_r=%p\n", strerror, strerror_r);
strerror=0x8049ec0, strerror_r=0x8049e202)。dlsym版本:
rtldDefault= dlopen(0, RTLD_NOW | RTLD_GLOBAL);
dlsym(rtldDefault, "strerror_r"); ==> strerror_r=0xb76544e0但
dlsym(rtldDefault, "strerror"); ==> strerror=0x8049ec03)。其他:
dlsym((void*)0, "strerror_r") ==> strerror_r=0xb76544e0
dlsym((void*)-1, "strerror_r") ==> strerror_r=0xb76544e0如何使用dlsym()获取strerror_r=0x8049e20
我已经先打印了strerror_r的地址,然后调用dlsym()。
strerror_r=0xb76544e0是错误的地址,我使用此地址调用strerror_r时什么也不做。
发布于 2012-08-10 19:02:02
如果您查看/usr/include/string.h中的strerror_r声明
/*可重入版本的GNU _r‘,
strerror'. There are 2 flavors of返回字符串并可能使用提供的临时缓冲区,也可能不使用提供的临时缓冲区,而POSIX _r’将字符串填充到缓冲区中。要使用POSIX版本,需要不带-D_GNU_SOURCE的-D_XOPEN_SOURCE=600或-D_POSIX_C_SOURCE=200112L,否则首选GNU版本。*/
然后是一些令人困惑的声明
使用gcc -save-temps和默认配置编译示例程序时,我得到了以下预编译声明:
extern int strerror_r (int __errnum, char *__buf, size_t __buflen)
__asm__ ("" "__xpg_strerror_r") __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__nonnull__ (2)));因此,看起来strerror_r函数链接到了符号__xpg_strerror_r。
实际上,对生成的二进制objdump -t a.out | grep strerror的检查
00000000 DF *UND* 00000000 GLIBC_2.3.4 __xpg_strerror_r所以,在问你的问题时,只需执行dlsym(rtldDefault, "__xpg_strerror_r")。
https://stackoverflow.com/questions/11899728
复制相似问题