BLOGTIMES
2008/12/30

_intel_fast_memsetや_intel_fast_memcpyのエラーが出るときは

  icc  linux  c  intel 
このエントリーをはてなブックマークに追加

プライベートなテスト環境にiccをインストールして使っているのですが、MySQLをiccを使ってリコンパイルしてみたら、libmysqlclientを使うプログラムがundefined symbol: _intel_fast_memsetというエラーを吐いて落ちるようになってしまいました。

どう考えてもicc周りのトラブルのようなのですが、解決方法がなかなか見つけられなくて困りましたが、下記のicc 8.0のリリースノートの情報で何とか解決することができました。

Linux 版インテル(R) C コンパイラ 8.0 リリースノート

高速メモリ Copy ルーチン

コマンドラインで -nostdlib を指定した場合やインテル C コンパイラのドライバからではなく、直接リンカを呼び出したことにより、標準のインテル・ライブラリに対してリンクが行われない場合の問題について次に説明します。

インテル C コンパイラは、_intel_fast_memcpy と _intel_fast_memset の 2 つのルーチンを使用して、ソースコードでは __builtin_memcpy と __builtin_memset にマクロ展開されていない memcpy 演算と memset 演算を行います。これらは、libirc にあります。gcc コンパイラを使用してアプリケーションをリンクしたり、リンカ ld を直接呼び出すと、これらの 2 つのルーチンが未解決のシンボルになります。このため、コンパイル・フェーズで使用したコンパイラ・オプションと同じものを使用して、インテル C コンパイラでリンクすることを推奨します。ただし、これらのルーチンを未定義の外部参照とみなす場合は、-lirc をリンク行に追加するか、または memcpy および memset が組込み形式にマクロ展開されるようにインクルードを変更して、再コンパイルします。IA-32 ベース・アプリケーション用インテル C コンパイラは、任意のプログラムのメインルーチンから intel_proc_init ルーチンを呼び出し、プロセッサが正しく設定されるようにします。また、このルーチンは libirc にも含まれています。これらのルーチンは glibc からのエントリポイントを使用するので、コマンドラインでは -lirc を -lc の前に配置する必要があります。

つまり、iccを使って作ったライブラリをiccを使わずにリンクするとこれらのシンボルが未解決のままになってしまうようです。このリリースに書かれているとおり、リンク時のオプションに-lircを加えてやると正常に動くようになりました。

そのほかの解決方法

再コンパイルが困難な場合には、環境変数 LD_PRELOAD を使ってライブラリを強制的にロードしてあげると言う方法もあります。

LD_PRELOAD=/opt/intel/Compiler/11.0/074/lib/ia32/libirc.so ./a.out

    トラックバックについて
    Trackback URL:
    お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
    このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/2864
    Trackbacks
    このエントリにトラックバックはありません
    Comments
    愛のあるツッコミをお気軽にどうぞ。[policy]
    古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
    コメントはありません
    Comments Form

    コメントは承認後の表示となります。
    OpenIDでログインすると、即時に公開されます。

    OpenID を使ってログインすることができます。

    Identity URL: Yahoo! JAPAN IDでログイン