I am creating an application where several processes are communicating through boost message queues. The queues are created using the message queue constructor as
message_queue(open_or_create, name, max_num_msg, max_msg_size);
I am using open_or_create for all the queues in all processes since there is not specified order in which the queues must be created.
max_num_msg = 200
and max_msg_size = 500000
.
Now creation seems all fine, but after sending messages over the queues for a while, I experience sudden crashes due to read access violations. Doing a bit of debugging has taken me to the definition of do_send
in message_queue.hpp
where an empty message header is obtained for writing the message
//Insert the first free message in the priority queue
ipcdetail::msg_hdr_t<VoidPointer> &free_msg_hdr = p_hdr->queue_free_msg(priority);
//Sanity check, free msgs are always cleaned when received
BOOST_ASSERT(free_msg_hdr.priority == 0);
BOOST_ASSERT(free_msg_hdr.len == 0);
The error happens at free_msg_hdr.priority == 0
because the address of free_msg_hdr
does not point to a readable location.
Doing a bit more research revealed that in the creation of the queue,
template<class VoidPointer>
inline message_queue_t<VoidPointer>::message_queue_t(open_or_create_t,
const char *name,
size_type max_num_msg,
size_type max_msg_size,
const permissions &perm)
//Create shared memory and execute functor atomically
: m_shmem(open_or_create,
name,
get_mem_size(max_msg_size, max_num_msg),
read_write,
static_cast<void*>(0),
//Prepare initialization functor
ipcdetail::msg_queue_initialization_func_t<VoidPointer>(max_num_msg, max_msg_size),
perm)
{}
the created shared memory object m_shmem
has a size that is too small to hold 200 messages of size 500000. This explains why the crashes are a bit unpredictable because still a smaller part of the memory is accessible so it takes some time to accidentally get into the inaccessible parts. However, I still have no clue why this is happening. Looking at the function get_mem_size(max_msg_size, max_num_msg)
it returns the right size but then after creation the size is smaller. If I then re-create the same queue it usually gets the right size and I never get any exceptions whatsoever. If anyone has any idea of why this could be happening, or suggestions on how to further debug this problem, it would be much appreciated.
I should probably mention that the application is compiled in Visual C++ in 32 bits and runs on Windows 10. Could the Windows shared memory implementation be causing a problem like this?