2016-06-05 19 views
0

Ich habe ein Problem mit einem C++ - Programm (einem Webserver) auf einem Shared-Host-Computer.Programme hängen beim Auslösen einer Ausnahme

Das Programm läuft gut auf meinem Entwicklungscomputer, aber wenn ich versuche, es auf dem Host-Rechner auszuführen, hängt es beim Versuch, eine Ausnahme zu werfen.

Dass es versucht, eine Ausnahme zu werfen, ist kein Problem; Wenn die Exception erfolgreich ausgelöst wurde, würde die Exception einige Stack-Frames aufgefangen und der Webserver würde weiter ausgeführt.

Hier ist der Stack-Trace des hängenden Fadens:

#0 __lll_lock_wait() at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:136 
#1 0x00007f18e559669a in _L_lock_1088() from /home/nr/lib/glibc-2.14.1/lib/libpthread.so.0 
#2 0x00007f18e55964fa in __pthread_mutex_lock (mutex=0x7f18e66b6930) at pthread_mutex_lock.c:82 
#3 0x00007f18e530f3db in __dl_iterate_phdr (callback=0x970100 <_Unwind_IteratePhdrCallback>, data=0x7f18e2fe9040) at dl-iteratephdr.c:42 
#4 0x00000000009714e3 in _Unwind_Find_FDE() 
#5 0x000000000096daf6 in uw_frame_state_for() 
#6 0x000000000096ed40 in uw_init_context_1() 
#7 0x000000000096f53e in _Unwind_RaiseException() 
#8 0x00000000008dfe7b in __cxa_throw() at ../../../../gcc-5.1/libstdc++-v3/libsupc++/eh_throw.cc:82 
#9 0x000000000054ff6e in Wt::WEnvironment::getCookie(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const() at /home/nr/dev/libraries/wt-3.3.4/src/Wt/WEnvironment.C:435 
#10 0x000000000069a372 in Wt::WebSession::handleRequest(Wt::WebSession::Handler&)() at /home/nr/dev/libraries/wt-3.3.4/src/web/WebSession.C:1388 
#11 0x000000000068a21c in Wt::WebController::handleRequest(Wt::WebRequest*)() at /home/nr/dev/libraries/wt-3.3.4/src/web/WebController.C:713 
#12 0x00000000004d815b in boost::asio::detail::completion_handler<boost::_bi::bind_t<void, boost::_mfi::mf1<void, Wt::WebController, Wt::WebRequest*>, boost::_bi::list2<boost::_bi::value<Wt::WebController*>, boost::_bi::value<http::server::HTTPRequest*> > > >::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long)() at /home/nr/dev/dist/boost/include/boost/bind/mem_fn_template.hpp:165 
#13 0x000000000056e4a2 in Wt::WIOService::run()() at /home/nr/dev/dist/boost/include/boost/asio/detail/task_io_service_operation.hpp:38 
#14 0x0000000000810ff3 in thread_proxy() 
#15 0x00007f18e5593cea in start_thread (arg=0x7f18e2fec700) at pthread_create.c:301 
#16 0x00007f18e52d8fcd in clone() at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115 

Da es fein auf der Entwicklung Maschine funktioniert, vermute ich, das Problem zu verschiedenen Versionen von gemeinsam genutzten Bibliotheken vorhanden verwendet werden kann, als die auf der Entwicklungsmaschine zu sein Hosting-Maschine, aber ich weiß nicht, was speziell. Ich verbinde alles, was ich kann, einschließlich libstdC++, um solche Probleme zu vermeiden.

Alle Vorschläge zur weiteren Diagnose dieses Problems sind willkommen.

EDIT: Wenn es hilft, läuft die Entwicklung Maschine Debian Jessie, während die Hosting-Maschine CentOS 6.8 läuft.

+1

Ein typisches Ergebnis von undefiniertem Verhalten. Und, ja, es sei denn, Sie sind sicher, dass die C++ - ABI zwischen den verschiedenen Versionen der gemeinsam genutzten Bibliotheken auf der Host + -Entwicklungsmaschine identisch ist, dies könnte definitiv das Problem sein. –

+0

Sperren Sie irgendetwas, bevor die Ausnahme ausgelöst wird? Sieht für mich so aus, als hätten Sie einen Mutex gesperrt, aber nicht freigegeben, wenn die Ausnahme ausgelöst wird. –

+0

@SamVarshavchik: Ich verbinde alle C++ Bibliotheken statisch. Die einzigen Bibliotheken, die dynamisch verbunden bleiben, sind C-Bibliotheken, wie 'glibc' und' libssl'. – HighCommander4

Antwort

1

Ich habe das Problem herausgefunden. Es war in der Tat mit verschiedenen Versionen von Shared Libraries verwandt, die auf der Entwicklungs-Hosting-Maschine vorhanden waren.

Ich habe bereits alle C++ - Bibliotheken statisch verknüpft, und nur C-Bibliotheken blieben dynamisch verknüpft. Bemerkenswerterweise blieb glibc dynamisch verknüpft, weil es statische Verknüpfung nicht gut unterstützt.

Die auf der Entwicklungsmaschine installierte glibc-Version war 2,19; auf dem Hosting-Rechner war es 2.12.

Wenn ich das Programm auf dem Hosting-Rechner läuft zunächst versucht, bekam ich einen Fehler in der Form:

./myapp: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by ./myapp) 

(Der Grund ist es eher für 2,14 gefragt wurde als 2,19, dass die Funktionalität meines Programm war tatsächlich verwendet, war in 2.14 und später, und glibc Versionen sind abwärtskompatibel.)

In einem Versuch, dieses Problem zu beheben, baute ich glibc 2.14, seine Binärdateien auf dem Host-Computer hochgeladen, und zeigte mein Programm auf sie mit LD_LIBRARY_PATH. Das machte den obigen Fehler weg, aber ich bekam jetzt den Hang, der mich dazu veranlasste, diese Frage zu stellen.

Der Grund für den Dreh raus, stellt sich heraus, ist, dass man glibc Komponente gibt, deren Pfad wird bei der Kompilierung in die ausführbare gebacken, und erhalten überschrieben nicht durch LD_LIBRARY_PATH - der Lader (ld-linux.so).

Also, ich war mit dem Glibc 2.12 Loader der Hosting-Maschine, zusammen mit den restlichen Bibliotheken von Glibc 2.14 - und das funktioniert nicht.

Ich löste dies durch den Linker-Befehl zu ändern, die das Programm auf der Entwicklungsmaschine produziert, auf dem Weg zu hart codieren 2,14 Loader auf dem Hosting-Maschine glibc, wie für das Schreiben, dass in this answer (Vielen Dank an @EmployedRussian beschrieben!).

Verwandte Themen