【发布时间】:2022-06-13 06:23:37
【问题描述】:
我有 2 个使用 boost 共享内存循环运行的进程。
在每次迭代中,进程调用check_sanity() 在共享内存中执行某些操作之前,我有一个场景,其中一个进程崩溃(仍在调查原因)并出现此错误:
/usr/local/include/boost/interprocess/mem_algo/detail/mem_algo_common.hpp:106: static void boost::interprocess::ipcdetail::memory_algorithm_common<MemoryAlgorithm>::assert_alignment(boost::interprocess::ipcdetail::memory_algorithm_common<MemoryAlgorithm>::size_type) [with MemoryAlgorithm = boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>; boost::interprocess::ipcdetail::memory_algorithm_common<MemoryAlgorithm>::size_type = long unsigned int]: Assertion `uint_ptr % Alignment == 0' failed.
./start.sh: line 20: 3034 Aborted (core dumped)
粉碎后,第二个进程卡在check_sanity()函数中,在第一个进程重新启动后,他也卡在那里。
我查看了 boost 源代码,发现check_sanity() 函数中有一个scoped lock mutex,并且那里有一个assert,所以我的猜测是assert 中的第一个进程在没有解锁的情况下崩溃scoped mutex.
boost共享内存check_sanity()源码:
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
bool rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
check_sanity()
{
//-----------------------
boost::interprocess::scoped_lock<mutex_type> guard(m_header);
//-----------------------
imultiset_iterator ib(m_header.m_imultiset.begin()), ie(m_header.m_imultiset.end());
size_type free_memory = 0;
//Iterate through all blocks obtaining their size
for(; ib != ie; ++ib){
free_memory += (size_type)ib->m_size*Alignment;
algo_impl_t::assert_alignment(&*ib);
if(!algo_impl_t::check_alignment(&*ib))
return false;
}
//Check allocated bytes are less than size
if(m_header.m_allocated > m_header.m_size){
return false;
}
size_type block1_off =
priv_first_block_offset_from_this(this, m_header.m_extra_hdr_bytes);
//Check free bytes are less than size
if(free_memory > (m_header.m_size - block1_off)){
return false;
}
return true;
}
目前,当这种情况发生时,我的丑陋解决方案是删除共享内存,重新启动两个进程,以便第一个进程创建一个新的有效共享内存。
解决这个问题的最佳方法是什么?
【问题讨论】:
-
在我看来最好的方法是完成导致未定义行为的实际崩溃的“原因调查”,并修复真正的错误。
标签: c++ boost shared-memory