GLAIBC_2.14準拠問題version`GLOIBC_2.14’not found


オリジナル:http://b.liuctic.com/2013/11/glibc_2-14-E 5%BC%E 5%AE%B 9%E 9%AE%E 9%A 2%98-lib 64 libc-so-6-version-glibc_2-14-not-found/
この問題は私がデスクトップマシンでbinaryをコンパイルした後、直接にターゲットサーバで実行します。
./mybin: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by ./mybin)
./mybin: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by ./mybin)
ローカルデスクトップのgccバージョンは4.6.3で、libcバージョンは2.15で、libstdc++バージョンはlibstdc+++で、so.1.6.16です。サーバーのgccバージョンは4.1.2で、libcバージョンは2.5で、libstdc++バージョンはlibstdc++です。
1バージョンの互換性のない関数を検索します。
~: objdump -T mybin | fgrep GLIBC_2.14
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.14 memcpy
mybinが見えますが、GLOIBC_を呼んでください。2.14のmemcpyを実現し、目標機で実行する:
#: objdump -T /lib64/libc.so.6 | fgrep memcpy
00000032be87bdb0 g DF .text 0000000000000465 GLIBC_2.2.5 memcpy
つまり、対象機のlibcは提供されただけです。memcpy@GLIBC_2.2.5の実現により、mybinが運転できなくなりました。
上のコマンドを1回実行します。(実際に呼び出したlibcパスを確認するためにlddを使用して)。
~: objdump -T /lib/x86_64-linux-gnu/libc.so.6 | fgrep memcpy
00000000000917f0 g iD .text 000000000000003c GLIBC_2.14 memcpy
000000000008bbd0 g iD .text 0000000000000047 (GLIBC_2.2.5) memcpy
これは本機で同時に使用できるということを示しています。memcpy@GLIBC_2.2.5とmemcpy@GLIBC_2.14の場合、最大互換性を保証するために、強制的にリンクできる方法がありますか?memcpy@GLIBC_2.2.5は?もちろんあります。そうでなければこの本を書いて何をしますか?
2.symverバインディングシンボルバージョンこの記事ではrealpathの例を示しています。Linking to Older Version ed Symbors(glibc)
#include 
#include 
#include 

__asm__(".symver realpath,realpath@GLIBC_2.2.5");
int main()
{
   char* unresolved = "/lib64";
   char  resolved[PATH_MAX+1];
   if(!realpath(unresolved, resolved))
      { return 1; }
   printf("%s
", resolved); return 0; }
このスキームは簡単な解コード内の明示関数呼び出しが可能である。mybinソースコードでは直接memcpy関数を使っていませんが、mybinリンクの他のライブラリでmemcpyを呼び出しています。明らかにこの方式は通用しません。
3–wrapオプションまずファイルのmemcpy.cを書いて、関数を定義します。wrap_memcpyを使用して、symverで指定を表示します。memcpy_glibc_2_2_5リンク先memcpy@GLIBC_2.2.5上です
#include 

void *__memcpy_glibc_2_2_5(void *, const void *, size_t);

asm(".symver __memcpy_glibc_2_2_5, memcpy@GLIBC_2.2.5");
void *__wrap_memcpy(void *dest, const void *src, size_t n)
{
    return __memcpy_glibc_2_2_5(dest, src, n); 
}
リンクする時にオプション-Wlを使います。–wrap=memcpy cmakeを使ってリンクをコンパイルするなら、CMakelists.txtに下記のオプションを追加します。
SET_TARGET_PROPERTIES( mybin PROPERTIES LINK_FLAGS "${LINK_FLAGS} -Wl,--wrap=memcpy" )
mybinを再生成した後、再びObjdumpを使って確認します。
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 memcpy
000000000047355c g DF .text 000000000000002d Base __wrap_memcpy
呼び出しが見えるのはmemcpy@GLIBC_2.2.5
4 GLOIBCXXバージョンの互換性の問題は二つの案が解決できます。一つはリンクlibstdc++の静的なライブラリです。もう一つは本機のlibstdc+.soを一緒に包装して発表します。LD_を設定します。リブラアルPATHはmybinに梱包されたlibstdc+.soを呼び出すことができます。
もう一つの問題を追加します。以前にlibstdc++はGPL契約だと言われていましたので、包装して発表したいなら、mybinのソースコードも提供しなければなりません。しかしまた検索したら、libstdc++はplin GPLではないことが分かりました。このような簡単なリンクアプリケーションのシーンでは問題ありません。この回答と関連リンクを見てください。
5 2010.3.11.29怒りは4の中で言葉が不詳であることを補充します。libstdc++をリンクする静的な倉庫です。直接包装してlibstdc+.soを発表すると、問題が発生する可能性があります。2.14の関数は、最初の問題を引き起こします。しかも、wrapで解決できません。libc.soを同時に包装するなら、libc.soの違うプラットフォームの互換性が悪いです。静的リンクlibstdc++を検索しましたが、動的リンクlibcは、康神のブログに迷い込んでしまい、怒って更新しました。この招待状を見ます:gcc静的なリンクからの討論、多くの手を学びました。
CMakelistsの中で簡単に多くなりました。式指定libstdc+.aでいいです。このようにして、静的リンクlibstdc++に達したが、動的リンクlibcの目的は達成された。
6 Referenceshttp://blog.kangkang.org/index.php/archives/17http://micro.nicholaswilson.me.uk/post/31855915892/…http://www.trevorpounds.com/blog/?p=103http://stackoverflow.com/questions/4032373/…https://gist.github.com/nicky-zs/7541169http://www.cmake.org/pipermail/cmake/2003-August/004244.htmlhttp://stackoverflow.com/a/3214398http://lwn.net/Articles/549573/