我爲離線渲染3D模型做了一個C++工具。渲染是使用OSMesa庫完成的。lib OSMesa離屏上下文創建在C++中失敗,但僅在靜態鏈接時才生效
這個軟件在一年多的時間裏工作得非常完美,我停下來做了6個月前的更新。與此同時,我的開發環境多次更新。
現在我再次編譯它,發現一個意外的錯誤。
該軟件的普通版本仍按預期工作,但靜態鏈接的版本是segfaulting。
我假設錯誤是在OSmesa配置/編譯/鏈接過程中的,而不是在庫代碼中,但任何有關更好的調試分段錯誤的建議,我們都很感激。
在嘗試了編譯過程的衆多變體而沒有成功之後,我現在很困惑。 任何人都可以在下面描述的某些步驟中看到我正在做的一些愚蠢的事情?
我重新編譯OSmesa庫靜態版本的共享庫的相同版本的工作在我的系統(12.0.6),禁止所有非必要的功能(使用的是基於Ubuntu系統, OSmesa LIB的無靜電版本可從資料庫):
./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)
但沒有分割故障如果製作我只是跳過OSmesa上下文創建步驟(顯然所有的3D渲染)
這是回溯:
#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靜態庫也編譯在同一臺機器上),但在同一工具的非靜態鏈接版本中沒有分段錯誤。
請運行gdb下的故障程序;在segv發佈後輸出'bt','info reg','frame 1; disassemble'。 ['mtx_init'使用了一些pthread](https://github.com/anholt/mesa/blob/master/include/c11/threads_posix.h#L200)mutex/mutex_attr函數,你在靜態線程中使用pthread有一些問題程式。這可能是一個壞主意,試圖改變你的需求的嚴格性(動態鏈接到glibc和pthread,爲了在較早的操作系統中運行,使用自己的glibc + pthreads和rpath來鏈接它們)。 – osgx
謝謝osgx,我打算做這個額外的調試,並將更新問題。使用帶有靜態鏈接程序的pthread有任何已知問題? – pangon
太好了,經過一番測試,結果證明實際上是導致問題的靜態鏈接的pthread庫。我的實際用例需要靜態鏈接大多數庫,但不是核心庫。可以將dl和pthread聯繫起來,解決我的問題。非常感謝。我對C++二進制文件鏈接到pthread的方式看到這個限制感到失望!我希望通過研究我可以在網上看到的案例來找出這種pthread限制的意義。再次感謝@osgx,如果你可以發佈這個問題的答案,我會將其標記爲正確的,給你賞金:) – pangon