c++ - name - error expected at end of input que significa
La creación de contexto fuera de pantalla de lib OSMesa falla en C++, pero solo cuando está vinculado estáticamente (1)
Esto es lo que obtengo al ejecutar la herramienta:
Segmentation fault (core dumped)
Pero no se produce ningún error de segmentación si simplemente omito el paso de creación del contexto OSmesa (y obviamente todo el renderizado 3D)
Entonces, hay un problema de la creación de OSmesa. Con su backtrace podemos ver que la función superior se ejecutó desde EIP de cero (saltar a NULL / call de NULL), por lo que hay una invocación de alguna función en mtx_init
, que es parte de la creación de contexto OS Mesa.
#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 (ctx=ctx@entry=0xdcc9b0) at main/shared.c:67
#4 0x000000000046e717 in _mesa_initialize_context (ctx=ctx@entry=0xdcc9b0, api=api@entry=API_OPENGL_COMPAT, visual=, share_list=share_list@entry=0x0, driverFunctions=driverFunctions@entry=0x7fffffffcd40) at main/context.c:1192
#5 0x000000000046c870 in OSMesaCreateContextAttribs (attribList=attribList@entry=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
¿Cuál fue la función? De acuerdo con las fuentes en línea de include / c11 / threads_posix.h: mtx_init()
en github , solo hay llamadas a pthread_mutex_init
, pthread_mutexattr_init
y varias otras funciones relacionadas con mutex de libpthread ( -lpthread
).
¿Por qué se produjo una llamada a NULL en lugar de una función real? Probablemente debido al uso de enlaces estáticos de glibc y / o libpthread. El problema exacto aún no se ha identificado en este momento (pude encontrar el informe de libpthread.a enlazado estáticamente en alguna biblioteca compartida que es incorrecta y nunca funcionará).
En su caso, solo hay un alias (fuerte) de pthread_mutex_init
en glibc / nptl / pthread_mutex_init.c (línea 150) strong_alias (__pthread_mutex_init, pthread_mutex_init)
y puede haber algún alias débil del símbolo en el glibc mismo, probablemente sin inicializar. Algunos estaban equivocados en sus opciones de vinculación y / o en su mente y no encontró / nptl/pthread_mutex_init.o
el nptl/pthread_mutex_init.o
(es parte del archivo libpthread.a) con el símbolo real en el ejecutable final (a menudo salta objetos no utilizados / innecesarios) de archivos .a y no los vincule en el ejecutable final), manteniendo la reubicación apuntando a NULL. Algún experto de glibc puede saber, Russian Employed es uno de los expertos en SO.
Sugiero vincular estáticamente solo a sus libs internas o probablemente también a -Wl,-Bstatic -lyour_lib -Wl,-Bdynamic
normales que no sean del sistema como mesa (puede usar -Wl,-Bstatic -lyour_lib -Wl,-Bdynamic
opciones para cambiar temporalmente la vinculación a static para libs enumeradas entre; o use la opción de trampa de -l:
como -l:libYour_lib.a
encontrada por Radek en la misma q.). Pero no enlace estáticamente a la mayoría de las librerías básicas de glibc como libc, libpthread, librt (hay algunos problemas en la vinculación estática de glibc cuando se usa nss: el sistema de destino debe tener exactamente la misma versión de glibc dinámico para permitir que nss funcione).
Si desea empacar su aplicación para máquinas antiguas y necesita algunas características de glibc, también puede intentar empacar su propia versión de libs de glibc compartidas con su aplicación; colóquelos en algún subdirectorio, agregue la opción rpath
de linker para cambiar las rutas de búsqueda de la biblioteca, también cambie la sección INTERP de ABI ld-linux.so.2 loader predeterminado a su propia copia de ld-linux.so.2 desde su versión de glibc, ... Y todavía tendrá problemas con kernels demasiado viejos, ya que los glibcs más nuevos requieren algunas características modernas (syscalls, structs) de kernel bastante nuevo.
O puede empaquetar su aplicación en algún tipo de contenedor como Docker, o alguna otra solución de aislamiento (¿o chroot?) Para tener siempre sus versiones de libs ...
ACTUALIZACIÓN: Informe encontrado de bt similar con NULL en lugar de implementación mutex desde nptl: https://bugzilla.redhat.com/show_bug.cgi?id=163083 "Programa C ++ enlazado estáticamente utilizando pthreads segfault" (2005-2007) pthread_mutex_init(&lock, NULL);
g++ -g -static foo.cpp -o foo -lpthread
where #0 0x00000000 in ?? () #1 0x08048232 in main () at foo.cpp:7
where #0 0x00000000 in ?? () #1 0x08048232 in main () at foo.cpp:7
Esto aparentemente se debe a ciertas funciones pthreads que no se incluyen en el ejecutable de salida. Este error puede duplicar # 115157, y me disculpo si es así, pero espero que el caso de prueba incluido sea útil.
Información adicional:
La sugerencia en # 115157 para vincular forzosamente en todo libpthread.a es una solución válida.
https://bugzilla.redhat.com/show_bug.cgi?id=115157 "ejecutables enlazados estáticamente con /usr/lib/nptl/libpthread.a fail" - 2004-2009 CERRADO WONTFIX
Jakub Jelinek 2004-10-29 05:26:10 EDT
En primer lugar, evite:
-static
si puede, solo crea problemas , tanto en la portabilidad como en otros.Si realmente necesita crear un binario estáticamente vinculado con
-lpthread
linked in, entonces simplemente use-Wl,--whole-archive -lpthread -Wl,--no-whole-archive
lugar de-pthread
. Cualquier otra cosa tiene realmente muchos problemas.
Hice una herramienta C ++ para la representación fuera de la pantalla de modelos 3D. La renderización se realiza utilizando la biblioteca OSMesa.
El software funcionó sin problemas durante más de un año, y me detuve para hacer actualizaciones de algo así como hace 6 meses. Mientras tanto, mi entorno de desarrollo se actualizó varias veces.
Ahora estaba compilando de nuevo y encontré un error inesperado.
La versión simple del software todavía funcionaba como se esperaba, pero la estáticamente vinculada es segfaulting.
Supongo que el error es mío en el procedimiento de configuración / compilación / vinculación de OSmesa y no en el código de la biblioteca, pero se agradece cualquier consejo sobre una mejor depuración de la falla de segmentación.
Después de haber probado numerosas variaciones del proceso de compilación sin éxito, ahora estoy bastante atascado. ¿Alguien puede ver algo estúpido que estoy haciendo en algunos de los pasos que se describen a continuación?
Recompuse una versión estática de la biblioteca OSmesa con la misma versión de la biblioteca compartida que está funcionando en mi sistema (12.0.6), deshabilitando todas las características no necesarias (usando un sistema basado en Ubuntu, no hay una versión estática de OSmesa lib) disponible en repositorios):
./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
Este es el comando de compilación de mi herramienta de renderizado fuera de pantalla:
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
Esta es una advertencia que obtuve mediante la compilación estática utilizando OSMesa, y estuvo presente incluso hace un año con el binario estático en funcionamiento:
/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
Esto es lo que obtengo al ejecutar la herramienta:
Segmentation fault (core dumped)
Pero no se produce ningún error de segmentación si simplemente omito el paso de creación del contexto OSmesa (y obviamente todo el renderizado 3D)
Esta es la traza inversa:
#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 (ctx=ctx@entry=0xdcc9b0) at main/shared.c:67 #4 0x000000000046e717 in _mesa_initialize_context (ctx=ctx@entry=0xdcc9b0, api=api@entry=API_OPENGL_COMPAT, visual=, share_list=share_list@entry=0x0, driverFunctions=driverFunctions@entry=0x7fffffffcd40) at main/context.c:1192 #5 0x000000000046c870 in OSMesaCreateContextAttribs (attribList=attribList@entry=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
Un binario estáticamente vinculado es un requisito estricto.
La falla de segmentación ocurre en la misma máquina que utilizo para compilar la herramienta (OSmesa lib está compilada también en la misma máquina), pero no hay falla de segmentación en la versión no estáticamente vinculada de la misma herramienta.