2017-05-31 7 views
3

3Dモデルのオフスクリーンレンダリング用のC++ツールを作成しました。レンダリングはOSMesaライブラリを使用して行われます。lib OSMesaオフスクリーンコンテキストの作成はC++では失敗しますが、静的にリンクされている場合のみです

ソフトウェアは完璧に1年以上働いていましたが、私は6ヶ月前のように更新を停止しました。その間、私の開発環境は何度も更新されました。

ここでもう一度コンパイルしていて、予期しないバグが見つかりました。

ソフトウェアの平凡なバージョンは、期待どおりに動作していましたが、静的にリンクされたものはセグメンテーションしています。

OSmesaの設定/コンパイル/リンクの手順ではなく、ライブラリコードでエラーが発生していると想定していますが、セグメンテーションフォールトのデバッグに関するアドバイスは有益です。

コンパイルプロセスのさまざまなバリエーションを成功させることなく試してみましたが、今はかなり固執しています。 誰かが愚かな何かを見ることができます私はいくつかの以下のステップでやっていますか?


私は、私のシステム(12.0.6)での作業のUbuntuベースのシステムを使用して(すべての非必要な機能を無効にされた共有ライブラリの同じバージョンでOSmesaライブラリの静的バージョンを再コンパイルOSmesa IIbの静的なバージョンがリポジトリから利用できません):

 
./configure \ 
    --disable-xvmc \ 
    --disable-glx \ 
    --disable-dri \ 
    --with-dri-drivers="" \ 
    --with-gallium-drivers="" \ 
    --disable-shared-glapi \ 
    --disable-egl \ 
    --with-egl-platforms="" \ 
    --enable-osmesa \ 
    --enable-gallium-llvm=no \ 
    --disable-gles1 \ 
    --disable-gles2 \ 
    --enable-static \ 
    --disable-shared 

これは私のオフスクリーンレンダリングツールのコンパイルコマンドです:

 
g++ -std=c++11 -Wall -O3 -g -static -static-libgcc -static-libstdc++ ./src/measure_model.cpp model.o thumbnail.o -o measure_model_debug -pthread -lOSMesa -ldl -lm -lpng -lz -lcrypto 

これは私がした警告です静的OSMesaを使用してコンパイルすることによって取得し、それが働いて、静的バイナリでも、一年前に存在した:

 
/home/XXX/XXX/backend/lambda/mesa/mesa-12.0.6/src/mesa/main/dlopen.h:52: warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking 

は、これは私がツールを実行しているから得るものです:

 
Segmentation fault (core dumped) 

しかしなしセグメンテーションフォールトがあります

 
#0 0x0000000000000000 in ??() 
#1 0x00000000004af20a in mtx_init (type=4, mtx=0xe10f70) at ../../include/c11/threads_posix.h:215 
#2 _mesa_NewHashTable() at main/hash.c:135 
#3 0x000000000052f295 in _mesa_alloc_shared_state ([email protected]=0xdcc9b0) at main/shared.c:67 
#4 0x000000000046e717 in _mesa_initialize_context ([email protected]=0xdcc9b0, [email protected]=API_OPENGL_COMPAT, visual=, [email protected]=0x0, [email protected]=0x7fffffffcd40) at main/context.c:1192 
#5 0x000000000046c870 in OSMesaCreateContextAttribs ([email protected]=0x7fffffffd290, sharelist=) at osmesa.c:834 
#6 0x000000000046ccdc in OSMesaCreateContextExt (format=, depthBits=, stencilBits=, accumBits=, sharelist=) at osmesa.c:660 
#7 0x0000000000468742 in generate_thumbnail(Model*, Json::Value)() 
#8 0x0000000000401c7d in main (argc=, argv=) at ./src/measure_model.cpp:107 
:私は単にOSmesaコンテキスト作成ステップをスキップした場合に生成(と明らかにすべての3Dレンダリング)

は、これがバックトレースであります

静的にリンクされたバイナリは厳しい要件です。

私はツールをコンパイルするのに使用する同じマシン(OSmesa静的ライブラリも同じマシンでコンパイルされます)でセグメンテーションフォルトが発生していますが、同じツールの静的にリンクされていないバージョンのセグメンテーションフォルトはありません。

+1

gdbで障害プログラムを実行してください。ライブ出力後の出力、bt、info reg、frame1。解体する。 ['mtx_init'はいくつかのpthreadを使用しています](https://github.com/anholt/mesa/blob/master/include/c11/threads_posix.h#L200)mutex/mutex_attr関数は、静的にpthreadの使用にいくつかの問題がありますプログラム。これは悪い考えかもしれませんが、あなたの要件の厳密さを変えようとします(glibcとpthreadへのリンクを古いOSで実行するためにglibc + pthreadsとrpathのコピーをそれらにリンクする)。 – osgx

+0

ありがとうosgx、私はこの追加のデバッグを行い、質問を更新します。静的にリンクされたプログラムでpthreadを使用すると、何か問題がありますか? – pangon

+1

素晴らしいことに、いくつかのテストの後、実際には問題を引き起こす静的にリンクされたpthreadライブラリが判明しました。私の実際のユースケースでは、ほとんどのライブラリを静的にリンクする必要がありますが、中核ライブラリはリンクしません。 dlとpthreadをdinamicallyにリンクさせて、問題を解決しても問題ありません。どうもありがとう。私はC++のバイナリがpthreadにリンクされているというこの制限を見るのが残念です!私はオンラインで見ることができるケースを勉強した後、このpthreadの制限の感覚を知りたいと思っています。ありがとうございました。もう一度@osgxに感謝します。この質問への回答を投稿できるのであれば、賞品を与えてくれます。 – pangon

答えて

2

これは私がツールを実行しているから得るものです: Segmentation fault (core dumped)

しかし、私は単純にOSmesaコンテキスト作成ステップ(と、明らかに、すべての3Dレンダリング)をスキップした場合に何のセグメンテーションフォールトが生成されません

OSmesaの作成にはいくつか問題があります。あなたのバックトレースでは、トップファンクションがEIPからゼロ(NULLへのジャンプ/ NULLの呼び出し)に実行されたことがわかります。したがって、OSメザコンテキスト作成の一部であるmtx_initにいくつかの関数の呼び出しがあります。

#0 0x0000000000000000 in ??() 
#1 0x00000000004af20a in mtx_init (type=4, mtx=0xe10f70) at ../../include/c11/threads_posix.h:215 
#2 _mesa_NewHashTable() at main/hash.c:135 
#3 0x000000000052f295 in _mesa_alloc_shared_state ([email protected]=0xdcc9b0) at main/shared.c:67 
#4 0x000000000046e717 in _mesa_initialize_context ([email protected]=0xdcc9b0, [email protected]=API_OPENGL_COMPAT, visual=, [email protected]=0x0, [email protected]=0x7fffffffcd40) at main/context.c:1192 
#5 0x000000000046c870 in OSMesaCreateContextAttribs ([email protected]=0x7fffffffd290, sharelist=) at osmesa.c:834 
#6 0x000000000046ccdc in OSMesaCreateContextExt (format=, depthBits=, stencilBits=, accumBits=, sharelist=) at osmesa.c:660 
#7 0x0000000000468742 in generate_thumbnail(Model*, Json::Value)() 
#8 0x0000000000401c7d in main (argc=, argv=) at ./src/measure_model.cpp:107 

機能は何ですか? online sources of include/c11/threads_posix.h: mtx_init() on githubによれば、pthread_mutex_initpthread_mutexattr_init、およびlibpthread(-lpthread)のいくつかの他のミューテックス関連関数の呼び出しのみがあります。

なぜ実際の関数の代わりにNULLへの呼び出しが生成されましたか? glibcやlibpthreadの静的リンクを使用している可能性があります。 正確な問題はまだ現時点では確認されていません(静的にリンクされているlibpthread.aのレポートが、一部の共有ライブラリに見つかりましたが、正しくないため動作しません)。

あなたのケースでpthread_mutex_initのみエイリアス(強いもの)のglibc/NPTL/pthread_mutex_init.cである(ライン150)strong_alias (__pthread_mutex_init, pthread_mutex_init)と、glibcの自体に、おそらく初期化されていないシンボルの一部弱いエイリアスが存在してもよいです。いくつかあなたのリンクオプションで間違っていたか、またはldという気になりました。nptl/pthread_mutex_init.o(これはlibpthread.aアーカイブの一部です)を実際のシンボルで最終実行可能ファイルに見つけたり、リンクしたりしませんでした(ldは.aアーカイブの未使用/それらを最終実行可能ファイルにリンクしない)、再配置がNULLを指していることを維持する。 glibcの専門家が知っているかもしれないが、Employed RussianはSOの専門家の1人です。

は、私は、あなたの内部のlibsにまたは多分もメサのような通常のシステム以外のLIBSに静的にリンクすることをお勧めします(LIBSのために静的に一時的な変更リンケージへuse -Wl,-Bstatic -lyour_lib -Wl,-Bdynamicオプションが間に記載されていること、または-l:libYour_lib.afound by Radekとして-l:のチートオプションを使用します同じqで)。しかしlibc、libpthread、librtのようなglibcの最も基本的なlibに静的にリンクしないでください(nssが使用されている場合、glibcの静的リンクにはいくつかの問題があります:ターゲットシステムはnssを動作させるために動的glibcと全く同じバージョンでなければなりません)。

古いマシン用にアプリケーションをパッケージ化したいが、glibcのいくつかの機能が必要な場合は、あなた自身のバージョンの共有glibcライブラリをアプリケーションにパックすることもできます。それらをいくつかのサブディレクトリに置き、ライブラリ検索パスを変更するためにリンカのオプションrpathを追加してください。INTERP section from default ABI ld-linux.so.2ローダを自分のglibcのバージョンから自分のld-linux.so.2のコピーに変更してください...そして、新しいカーネルのいくつかの現代的な機能(syscalls、structs)が必要になります。

それとも、ドッカー状の容器のいくつかの並べ替え、または他のいくつかのisolationソリューションにアプリケーションをパックすることができ、常にLIBSのあなたのバージョンを持っている...

UPDATE(またはchrootの?):類似したBTのジャストfound報告代わりNPTLからミューテックス実装のNULLで:https://bugzilla.redhat.com/show_bug.cgi?id=163083これは、出力実行中に含まれていない特定のpthreadの機能に明らかに起因している(2005から2007)pthread_mutex_init(&lock, NULL);g++ -g -static foo.cpp -o foo -lpthreadwhere #0 0x00000000 in ??() #1 0x08048232 in main() at foo.cpp:7

「静的にリンクされたC++プログラムを使用してpthreadのは、セグメンテーションフォールトであろう」。このバグは#115157と重複する可能性があります。もしそうなら謝罪しますが、含まれているテストケースが役立つことを願っています。

追加情報:

提案#115157で強制的にlibpthread.aの全てにリンクするには、有効な回避策です。2004-2009 CLOSED WONTFIX

ヤクブJelinekの2004年10月29日午前五時26分10秒EDT

- "/usr/lib/nptl/libpthread.aで静的にリンクされた実行ファイルは失敗"

https://bugzilla.redhat.com/show_bug.cgi?id=115157

まず、-staticを避けてください。、 の両方の移植性が問題になる場合があります。

あなたは本当に内のリンク-lpthread と静的にリンクされたバイナリを作成する必要がある場合は、はちょうど-Wl,--whole-archive -lpthread -Wl,--no-whole-archive の代わり-pthreadを使用しています。それ以外には本当に多くの問題があります。

関連する問題