ошибки seg из-за многопоточности (с использованием библиотек boost) - PullRequest
2 голосов
/ 29 августа 2009

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

Мы отладили с использованием gdb (в Eclipse), и я обнаружил, что ошибки seg возникают во время вызовов функций в коде повышения, т.е. я пытаюсь получить доступ к записи разреженной матрицы, а трассировка стека переходит в код повышения и умирает в какой-то момент (не всегда в одной и той же точке) в этих файлах.

Я запутался, потому что эти матрицы размещены в отдельных потоках, а все общие ресурсы защищены мьютекс-блокировками. Кроме того, я не думал, что многопоточность часто приводила к сбоям сегмента, просто множественный доступ и неверные данные. Тем не менее, я, очевидно, не имел опыта многопоточного программирования, поэтому я надеялся, что кто-то, кто более опытен в этой области, сможет дать какой-то совет.

Я использую систему boost управляемого make, и пример команды компиляции:

g++ -DNDEBUG -I"/usr/local/include/boost-1_38" -I/usr/local/include -I"/home/scandido/workspace/BigSHOT/src" -I"/home/scandido/workspace/BigSHOT/src/base" -O3 -Wall -c -fmessage-length=0 `freetype-config --cflags` -pthread -MMD -MP -MF"src/utils/timing_info.d" -MT"src/utils/timing_info.d" -o"src/utils/timing_info.o" "../src/utils/timing_info.cpp"

и команда компоновщика

g++ -L"/usr/local/lib" -L/usr/local/lib -o"BigSHOT"  ./src/utils/timing_info.o ... many more objects ... ./src/base/pomdp/policy_fn/EventDriven.o ./src/base/pomdp/policy_fn/Greedy.o  ./src/anotheralgorithm.o   -lboost_serialization-gcc43-mt -lpthread -lboost_thread-gcc43-mt -lboost_program_options-gcc43-mt -lboost_iostreams-gcc43-mt -lpng -lpngwriter -lz -lfreetype

Вот трассировка стека для потока, который сегментирует ошибки:

Thread [5] (Suspended: Signal 'SIGSEGV' received. Description: Segmentation fault.) 
    17 boost::numeric::ublas::mapped_matrix<bool, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::map_std<unsigned long, bool, std::allocator<std::pair<unsigned long const, bool> > > >::operator() /usr/local/include/boost-1_38/boost/numeric/ublas/matrix_sparse.hpp:377 0x000000000041c328 
    16 BigSHOT::Fire1FireState::get_cell() /home/scandido/workspace/BigSHOT/src/systems/fire1/pomdp/Fire1State.cpp:51 0x0000000000419a75    
    15 BigSHOT::Fire1SquareRegionProbObsFn::operator() /home/scandido/workspace/BigSHOT/src/systems/fire1/obs_fn/Fire1SquareRegionProbObsFn.cpp:92 0x000000000042ac37   
    14 BigSHOT::Fire1SquareRegionProbObsFn::operator() /home/scandido/workspace/BigSHOT/src/systems/fire1/obs_fn/Fire1SquareRegionProbObsFn.cpp:66 0x000000000042a8bf   
    13 BigSHOT::BayesFilterFn<BigSHOT::Fire1Belief, BigSHOT::Fire1State, BigSHOT::Fire1Action, BigSHOT::Fire1Observation>::update() /home/scandido/workspace/BigSHOT/src/base/pomdp/filter_fn/BayesFilterFn.h:50 0x0000000000445c3b 
    12 BigSHOT::HyperParticleFilter<BigSHOT::Fire1Belief, BigSHOT::Fire1Action, BigSHOT::Fire1Observation>::future_evolution() /home/scandido/workspace/BigSHOT/src/base/hpf/HyperParticleFilter.h:127 0x00000000004308e0   
    11 BigSHOT::HyperParticleFilter<BigSHOT::Fire1Belief, BigSHOT::Fire1Action, BigSHOT::Fire1Observation>::hyperfilter() /home/scandido/workspace/BigSHOT/src/base/hpf/HyperParticleFilter.h:86 0x000000000043149b 
    10 BigSHOT::HyperParticleFilterSystem<BigSHOT::HyperCostFn<BigSHOT::Fire1Belief, BigSHOT::Fire1Action>, BigSHOT::PolicyFn<BigSHOT::Fire1Belief, BigSHOT::Fire1Action>, BigSHOT::Fire1Belief, BigSHOT::Fire1Action, BigSHOT::Fire1Observation>::next_stage() /home/scandido/workspace/BigSHOT/src/base/hpf/HyperParticleFilter.h:189 0x0000000000446180  
    9 hyperfilter() /home/scandido/workspace/BigSHOT/src/anotheralgorithm.cpp:126 0x0000000000437798    
    8 hf_thread_wrapper() /home/scandido/workspace/BigSHOT/src/anotheralgorithm.cpp:281 0x0000000000437cd9  
    7 boost::_bi::list1<boost::_bi::value<int> >::operator()<void (*)(int), boost::_bi::list0>() /usr/local/include/boost-1_38/boost/bind.hpp:232 0x000000000043f25a    
    6 boost::_bi::bind_t<void, void (*)(int), boost::_bi::list1<boost::_bi::value<int> > >::operator() /usr/local/include/boost-1_38/boost/bind/bind_template.hpp:20 0x000000000043f298 
    5 boost::detail::thread_data<boost::_bi::bind_t<void, void (*)(int), boost::_bi::list1<boost::_bi::value<int> > > >::run() /usr/local/include/boost-1_38/boost/thread/detail/thread.hpp:56 0x000000000043f2b6   
    4 thread_proxy()  0x00007f28241c893f    
    3 start_thread()  0x00007f28243d93ba    
    2 clone()  0x00007f2822a4ffcd   
    1 <symbol is not available> 0x0000000000000000  

Строка кода, где это происходит, является второй из этого блока:

const_reference operator () (size_type i, size_type j) const {
  const size_type element = layout_type::element (i, size1_, j, size2_);
  const_subiterator_type it (data ().find (element));

Я хотел бы повторить, что ошибка сегмента не всегда возникает в одном и том же месте кода, но всегда при выполнении чего-либо в буст-коде.

Заранее спасибо за помощь!

1 Ответ

5 голосов
/ 30 августа 2009

Похоже, что ошибки могут возникать из других, хорошо отлаженных библиотек (или даже из стандартной библиотеки!), Если вы повредили кучу или свободное хранилище, например, путем двойного освобождения (или двойного удаления) указателя, обращаясь к указатель, который уже был освобожден (или удален), освобождает (или удаляет) указатель, который не был выделен, используя delete, если вы должны были использовать delete [] или наоборот, и т. д.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...