9

私は特に OpenGL に使用することを目的としたクロスプラットフォーム ウィンドウ ライブラリに取り組んでおり、現在は Linux に焦点を当てています。私は glload を使用して OpenGL 拡張機能を管理しています。これは、後で使用する他のライブラリと一緒に.so. この `.so は予想どおり動的にロードされていますが、実行時にプログラムは次の出力を返します (読みやすいように手動でラップされています)。

_dist/x64-linux-debug/bin/test: Symbol `glXCreateContextAttribsARB' has \
different size in shared object, consider re-linking

今、明らかに私は再リンクを試み、プロジェクト全体を何度も再構築しました(魔法のようにすべてが良くなることを盲目的に望んでいるだけでなく、テストしています)。プログラムは、期待どおりにログ出力を生成するため、喜んで実行されるようです。nm「シンボル」が.so

nm _dist/x64-linux-debug/lib64/libvendor.so | grep glXCreateContextAttribsARB
00000000009e0e78 B glXCreateContextAttribsARB

定義されているreadelfシンボルをよく見ると、次のようになります (ここでも、書式設定のために最初の 3 行を手動でラップしています)。

readelf -Ws _dist/x64-linux-debug/bin/test \
_dist/x64-linux-debug/lib64/libvendor.so | \
grep glXCreateContextAttribsARB
   348: 000000000062b318  8 OBJECT  GLOBAL DEFAULT  26 glXCreateContextAttribsARB
   421: 000000000062b318  8 OBJECT  GLOBAL DEFAULT  26 glXCreateContextAttribsARB
  1370: 00000000009e0e78  8 OBJECT  GLOBAL DEFAULT  25 glXCreateContextAttribsARB
 17464: 00000000009e0e78  8 OBJECT  GLOBAL DEFAULT  25 glXCreateContextAttribsARB

何を試して調べればよいのか本当にわからないので、これが私が提供できるすべてのことではないかと心配しています。私が言ったように、もっと多くの情報が必要になると確信しているので、私ができることを提供します. プロジェクトのルートからこれらのコマンドを実行しています。

4

4 に答える 4

5

wilsonmichaelpatrick の答えはほとんど正しいですが、使用gdbは問題を見つけるための最速の方法ではない可能性が高く、非デバッグ ビルドの場合はまったく機能しない可能性があります。

まず、実際に問題があることを確認する必要があります。

readelf -Ws _dist/x64-linux-debug/bin/test _dist/x64-linux-debug/lib64/libvendor.so |
  grep glXCreateContextAttribsARB

testこれにより、とで定義されているシンボルがlibvendor.so異なるサイズで表示されます。

次に、フラグを付けて再リンクtestします。これにより、どのオブジェクト ファイル (またはライブラリ) が (異なる) 定義を提供しているかがわかります。libvendor.so-Wl,-y,glXCreateContextAttribsARB

最後に、上記のオブジェクト ファイルを生成するソースを-E-dDフラグで前処理し、それらの違いを確認します。

アップデート:

私はそれが言っていることを消化するのに助けが必要です

無力にならないでください。を読むman readelfか、手で実行してください。次のように表示されます。

readelf -Ws /bin/date | head -5

Symbol table '.dynsym' contains 75 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __ctype_toupper_loc@GLIBC_2.3 (2)

これにより、取得したデータの意味がわかります。特に、これは intestと inのシンボルのサイズがlibvendor.so同じであることを示しています ( 8)。したがって、問題はこれら 2 つの ELF ファイルではなく、別の場所にあります。他のライブラリで実行readelfし、サイズが異なるの定義を探します。その後、残りの手順に従います。glXCreateContextAttribsARB

于 2013-02-25T02:49:20.400 に答える
3

ランタイムは、共有オブジェクトでコンパイルされた glXCreateContextAttribsARB と、メイン プログラムでコンパイルされた glXCreateContextAttribsARB (または、以前にリンクされた他の共有オブジェクトでさえ) のサイズが異なることに気付きます。つまり、共有オブジェクトとそのオブジェクトを参照するその他のものの個別のビルドでは、これが定義されている別のコード (おそらく共有オブジェクト内) を参照する必要があります。これは、異なるファイルを見ているために発生する場合もあれば、同じファイルの異なる解釈を引き起こす異なる #defines が原因で発生する場合もあります。理由が何であれ、同じシンボル (構造体など) が、実行時にリンクされるすべてのもので同じ方法で (つまり、同じメンバー変数とサイズで) 定義されていることを確認する必要があります。

コードの 2 つの部分が実行時に同じビットのメモリを異なる方法で解釈する場合、これは大惨事であるため、実行を拒否することは実際には非常に良いことです。(このまま進めば何かが起こるといっても過言ではありません。)

実行可能ファイルを gdb にロードして (実行せずに)、次のように入力してみてください。

info types

定義されている場所を確認し、共有オブジェクトを gdb にロードして (実行せずに)、info typesそこで別の操作を行って、それぞれが何を見ていると考えているかを確認します。同じ場合は、プリプロセッサ ディレクティブを確認してください。

于 2013-02-24T19:42:42.787 に答える