2016-06-05 6 views
0

У меня проблема с программой на C++ (веб-сервере) на общей хостинговой машине.Программы зависают при выдаче исключения

Программа отлично работает на моей машине разработки, но когда я пытаюсь запустить ее на хостинге, она зависает при попытке выбросить исключение.

То, что он пытается выбросить исключение, не является проблемой; если ему удастся выбросить исключение, исключение поймает несколько кадров стека, и веб-сервер продолжит работу.

Вот трассировка стека висящей нити:

#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 

Поскольку он работает отлично на машине развития, я подозреваю, что проблема может быть связана с различными версиями общих библиотек присутствует на машине развития, чем хостинг, но я не знаю, что конкретно. Я связываю все, что могу, статически, включая libstdC++, чтобы избежать подобных проблем.

Любые предложения о том, как диагностировать эту проблему дальше, оцениваются.

EDIT: Если это помогает, машина развития работает Debian Jessie, в то время как хостинг машина работает CentOS 6.8.

+1

Типичный результат неопределенного поведения. И да, если вы не уверены, что C++ ABI одинаково между разными версиями разделяемых библиотек на машине с хостом +, это определенно может быть проблемой. –

+0

Запираете ли вы что-нибудь до того, как будет выброшено исключение? Мне кажется, что вы заблокировали мьютекс, но не выпустили его, когда выбрано исключение. –

+0

@SamVarshavchik: Я статически связываю все библиотеки C++. Единственными библиотеками, которые остаются динамически связанными, являются библиотеки C, такие как 'glibc' и' libssl'. – HighCommander4

ответ

1

Я понял, что проблема. Это действительно связано с различными версиями разделяемых библиотек, присутствующими на машине разработки или хостинга.

Я уже связывал все библиотеки C++ статически, и только библиотеки C оставались динамически связанными. Примечательно, что glibc оставался динамически связанным, потому что он не поддерживает статическое соединение.

Версия glibc, установленная на машине разработки 2.19; на хостинге это было 2.12.

Когда я первоначально пытался запустить программу на хостинг машины, я получил сообщение об ошибке вида:

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

(Причина, по которой просило 2,14, а не 2,19, что функциональность моей программы фактически, был представлен в 2.14 и более поздних версиях, а версии glibc совместимы с обратной связью.)

В попытке решить эту проблему я построил glibc 2.14, загрузил свои двоичные файлы на хостинг-машину и указал на свою программу для них используя LD_LIBRARY_PATH. Это заставило вышеупомянутую ошибку уйти, но теперь я получил зависание, что побудило меня опубликовать этот вопрос.

Причина зависание, то оказывается, что есть один Glibc компонент, чей путь выпекают в исполняемый файл во время компиляции, а не получить переопределены LD_LIBRARY_PATH - загрузчик (ld-linux.so).

Итак, я использовал загрузчик glibc 2.12 хостинг-машины вместе с остальными библиотеками от glibc 2.14 - и это не работает.

Я решил это, изменив команду компоновщика, которая произвела программу на машине разработки, до жесткого кода до пути к загрузчику glibc 2.14 на хостинге, как описано в this answer (большое спасибо @EmployedRussian за это!).

Смежные вопросы