dlsym()返回符号的奇怪地址

时间:2012-08-10 10:24:35

标签: c symbols dlsym

1)。直接打印功能地址:

printf("strerror=%p, strerror_r=%p\n", strerror, strerror_r);
strerror=0x8049ec0, strerror_r=0x8049e20

2)。 dlsym版本:

rtldDefault= dlopen(0, RTLD_NOW | RTLD_GLOBAL);
dlsym(rtldDefault, "strerror_r"); ==> strerror_r=0xb76544e0

dlsym(rtldDefault, "strerror"); ==> strerror=0x8049ec0

3)。其它:

dlsym((void*)0, "strerror_r") ==> strerror_r=0xb76544e0
dlsym((void*)-1, "strerror_r") ==> strerror_r=0xb76544e0

如何使用strerror_r=0x8049e20获取dlsym()

我先打印了strerror_r的地址,然后调用dlsym()。

strerror_r = 0xb76544e0是错误的地址,我用这个地址调用strerror_r什么都不做。

1 个答案:

答案 0 :(得分:1)

如果您查看strerror_r/usr/include/string.h的声明:

  

/ * strerror'. There are 2 flavors of strerror_r'的可重入版本,GNU返回字符串      并且可能使用或不使用提供的临时缓冲区和POSIX      它将字符串填充到缓冲区中。      要使用POSIX版本,请-D_XOPEN_SOURCE = 600或-D_POSIX_C_SOURCE = 200112L      不需要-D_GNU_SOURCE,否则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")