私は最近、文字列ルーチン (memcpy、memset、および memmove) のいくつかの置換を作成しました。これらのルーチンを含むライブラリがコンパイル/リンク行で指定されている場合、これらは同じ名前のシステム標準ライブラリ ルーチンよりも優先されることを理解しています。すでに間違っている場合は、お知らせください。
これは、私が行ったすべてのテストで正しく機能します (正しいルーチンが存在し、glibc ルーチンが存在しないことを逆アセンブルによって確認しました)。
1)-gを使用して同じライブラリに別のファイルを構築します(-O2を構築していました)
2) このファイルには memset への明示的な呼び出しがあります
3a) コンパイル時のオプションが、この memset が gcc によってインライン化されるように機能する場合、すべて問題ありません
3b) ただし、オプションによって memset 呼び出しのインライン化が無効になり、それがなければインライン化される場合、ライブラリはビルドされますが、ライブラリを使用してアプリケーションを静的にリンクすると、重複シンボル リンカ エラーが発生します。シンボルの他のインスタンスはシステム ライブラリの memset。
基本的に、ライブラリの 2 つのバージョン (数百のソース ファイル) をビルドできます。1 つのディレクトリの make CFLAGS を -O1 -g から -g に変更することで、このライブラリを使用するとリンカー エラーをトリガーできます。
作業バージョンを取得して nm で実行すると、テスト ケースにリンクされているルーチンを含む memset への未定義の参照が多数あることがわかります。したがって、作業ケースで memset を解決しようとする必要があることがわかります。これを壊れたライブラリの nm 出力と比較すると、いくつかの余分な未定義の memcpy および memset 参照が表示されます。memset が最初のケース (私のルーチン) で解決された場合、2 番目のケースで解決されるはずです。
詳細なコンパイラ出力も調べて、この 1 つのライブラリへのパスを除いて、リンク行が両方のケースでまったく同じであることを確認しました。
ここには、非常に不可解なことが 2 つあります (その他の無数の問題の中でも)。
1) -O1 -g で構築されたライブラリ内のファイルが -g とは異なる方法でリンクされるのはなぜですか?
2) ユーザー ライブラリ内の交換 memset がシステム memset と競合するのはなぜですか?
大賞の場合、1) はどのように 2) を引き起こしますか?