0

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 什么都不做。

4

1 回答 1

1

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

/* strerror_r'的可重入版本strerror'. There are 2 flavors of,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")

于 2012-08-10T11:02:01.913 回答