Ho un sistema Ubuntu 13.04 con l'ultima versione SVN delle librerie Boost C++ installate. L'installazione Boost è stata realizzata utilizzando la versione nativa del sistema gcc
, v4.7.3. Uso Boost abbastanza estensivamente e funziona molto bene quando compilo usando gcc
; Ho usato molti di questi, incluso Boost.Thread (di cui parlerò più avanti), senza problemi.Segfault durante l'inizializzazione statica quando si collega Boost gcc-built in un programma compilato Intel C++
Il mio problema si verifica se provo a creare un programma utilizzando il compilatore Intel C++ (ho utilizzato personalmente alcune versioni diverse nella serie v13.x) che si collegano con le librerie Boost installate. Quando lo faccio, ottengo un errore di segmentazione subito dopo l'avvio del programma; sembra verificarsi durante l'inizializzazione statica della libreria Boost.Thread. Ecco un semplice programma di esempio:
#include <boost/version.hpp>
#include <boost/thread.hpp>
int main()
{
boost::this_thread::sleep(boost::posix_time::seconds(1));
}
compilo usando Intel C++:
icpc test.cc -lboost_thread -lboost_system -I/path/to/boost/inc/dir -L/path/to/boost/lib/dir
Come ho detto, quando ho eseguito il programma risultante, ottengo un segfault quasi immediato. Via gdb
, l'analisi dello stack dal punto di segfault è la seguente:
#0 0x00007ffff79b6351 in boost::exception_ptr boost::exception_detail::get_static_exception_object<boost::exception_detail::bad_exception_>()() from ./libboost_thread.so.1.55.0
#1 0x00007ffff79b02e1 in _GLOBAL__sub_I_thread.cpp() from ./libboost_thread.so.1.55.0
#2 0x00007ffff7de9876 in call_init ([email protected]=0x7ffff7ff9a10, [email protected]=1,
[email protected]=0x7fffffffe0b8, [email protected]=0x7fffffffe0c8) at dl-init.c:84
#3 0x00007ffff7de9930 in call_init (env=<optimized out>, argv=<optimized out>,
argc=<optimized out>, l=0x7ffff7ff9a10) at dl-init.c:55
#4 _dl_init (main_map=0x7ffff7ffe268, argc=1, argv=0x7fffffffe0b8, env=0x7fffffffe0c8)
at dl-init.c:133
#5 0x00007ffff7ddb68a in _dl_start_user() from /lib64/ld-linux-x86-64.so.2
#6 0x0000000000000001 in ??()
#7 0x00007fffffffe391 in ??()
#8 0x0000000000000000 in ??()
Non molto illuminante, ma è chiaramente morire durante l'inizializzazione di libboost_thread.so
. Se ricostruisco Boost compresi i simboli di debug, allora ottengo un quadro leggermente migliore:
#0 shared_count (r=..., this=0x7ffff7bbc5f8 <boost::exception_ptr boost::exception_detail::get_static_exception_object<boost::exception_detail::bad_exception_>()::ep+8>)
at ./boost/smart_ptr/shared_ptr.hpp:328
#1 shared_ptr (this=0x7ffff7bbc5f0 <boost::exception_ptr boost::exception_detail::get_static_exception_object<boost::exception_detail::bad_exception_>()::ep>) at ./boost/smart_ptr/shared_ptr.hpp:328
#2 exception_ptr (ptr=..., this=0x7ffff7bbc5f0 <boost::exception_ptr boost::exception_detail::get_static_exception_object<boost::exception_detail::bad_exception_>()::ep>)
at ./boost/exception/detail/exception_ptr.hpp:53
#3 boost::exception_detail::get_static_exception_object<boost::exception_detail::bad_exception_>() at ./boost/exception/detail/exception_ptr.hpp:130
#4 0x00007ffff79b02e1 in __static_initialization_and_destruction_0 (__initialize_p=<optimized out>, __priority=<optimized out>) at ./boost/exception/detail/exception_ptr.hpp:143
#5 _GLOBAL__sub_I_thread.cpp(void)() at libs/thread/src/pthread/thread.cpp:767
#6 0x00007ffff7de9876 in call_init ([email protected]=0x7ffff7ff9a10, [email protected]=1, [email protected]=0x7fffffffe0b8, [email protected]=0x7fffffffe0c8) at dl-init.c:84
#7 0x00007ffff7de9930 in call_init (env=<optimized out>, argv=<optimized out>, argc=<optimized out>, l=0x7ffff7ff9a10) at dl-init.c:55
#8 _dl_init (main_map=0x7ffff7ffe268, argc=1, argv=0x7fffffffe0b8, env=0x7fffffffe0c8) at dl-init.c:133
#9 0x00007ffff7ddb68a in _dl_start_user() from /lib64/ld-linux-x86-64.so.2
#10 0x0000000000000001 in ??()
#11 0x00007fffffffe391 in ??()
#12 0x0000000000000000 in ??()
Non è chiaro per me che cosa/oggetto globale statica sta causando il problema si verifichi, quindi non sono sicuro di come procedere. Ho duplicato questo comportamento utilizzando un numero di versioni Boost e alcune versioni diverse del compilatore Intel C++ nella serie v13.x, che è l'unica versione a cui ho accesso al momento. Ho provato ogni permutazione del compilatore (ad esempio, ho costruito Boost con entrambi gli gcc
e icpc
e ho creato la mia applicazione di test anche con entrambi); l'unica permutazione che fallisce è dove Boost è costruito con gcc
e la mia applicazione di test è costruita usando icpc
. In ogni altro caso, l'applicazione di test viene eseguita correttamente.
Detto questo, si potrebbe essere indotti alla risposta ovvia:
- Perché non basta ricostruire Boost utilizzando
icpc
e chiamare un giorno? Questo approccio sembra essere efficace, data la mia sperimentazione, ma ho clienti che amano usareicpc
per costruire il mio software. È probabile che gli stessi clienti abbiano installato un pacchetto Boost distribuito su Linux; non hanno alcun controllo sull'ambiente di generazione che è stato utilizzato per generare quel pacchetto (e, con ogni probabilità, è stato compilato usando logcc
in ogni caso). Pertanto, se è possibile supportare una configurazione mista a compilatore, sarebbe ottimale.
Qualcuno ha qualche consiglio su come risolvere questo problema di inizializzazione statica?
Non so davvero icpc ma hai provato a collegarti con pthread? Solo una supposizione selvaggia. – PeterT