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'. There are 2 flavors ofstrerror_r' の再入可能バージョン。文字列を返し、提供された一時バッファを使用する場合と使用しない場合がある GNU と、文字列をバッファに入れる POSIX のもの。POSIX バージョンを使用するには、-D_XOPEN_SOURCE=600 または -D_GNU_SOURCE なしの -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").

于 2012-08-10T11:02:01.913 に答える