Opened 8 years ago

Last modified 8 years ago

#10180 new Bugs

shared_memory_object assertion when used with boost unit test

Reported by: andrew.lang@… Owned by: Ion Gaztañaga
Milestone: To Be Determined Component: interprocess
Version: Boost 1.55.0 Severity: Problem
Keywords: Cc:

Description

I am running with Visual Studio 2010, and boost 1.55. When I run a simple unit test with shared_memory_object, I get an assertion on shutdown. The test itself creates a shared memory object, maps it to memory, and writes to it; it then opens a shared memory object of the same name and reads from it. This works fine.

On exit, the fini_atomic_func functor in intermodule_singleton_common is run to clean up. This does the following:

         ref_count_ptr *rcount = intermodule_singleton_helpers::thread_safe_global_map_dependant
         <ThreadSafeGlobalMap>::find(m_map, typeid(C).name());
         //The object must exist
         BOOST_ASSERT(rcount);

The assertion fails. In the debugger I can see that typeid(C).name() has returned a rubbish string, and therefore no map entry is found. When that same code is executed in init_atomic_func, typeid(C).name() returns "struct boost::interprocess::ipcdetail::windows_bootstamp" as expected. Following the relevant memory address in the debugger, I see that the typeid string is erased in the unit test's framework::shutdown() function. This is done deliberately to eliminate fake memory leak reports from the typeid strings. See boost\test\impl\framework.ipp.

Unfortunately the interprocess cleanup is done via a handler registered with std::atexit, which guarantees it will be after framework has run shutdown. I don't see any options on either side (boost unit test or boost interprocess) which would allow the order to be fixed up.

Simplest code to reproduce:

#include <boost/test/unit_test.hpp>
#include <boost/interprocess/shared_memory_object.hpp>
namespace IP = boost::interprocess;

BOOST_AUTO_TEST_SUITE( TestSharedMemory )
BOOST_AUTO_TEST_CASE( CauseAssertionFailure )
{
   IP::shared_memory_object lShared( IP::open_only, "test_string", IP::read_only );
   BOOST_REQUIRE( lShared.get_name() != 0 );
}
BOOST_AUTO_TEST_SUITE_END()

Change History (2)

comment:1 by andrew.lang@…, 8 years ago

Component: Noneinterprocess
Owner: set to Ion Gaztañaga

Setting the component to interprocess; could also be considered a unit test problem.

This doesn't happen on Linux.

comment:2 by Ion Gaztañaga, 8 years ago

I don't see any option to fix this if Boost.Test prevents correct cleanup code in atexit(),as typeid should be available. However, please test Boost 1.56 RC, the global singleton logic is now triggered lazily and if boost.Test does the cleanup in a global destructor, Interprocess cleanup might be performed before that.

Note: See TracTickets for help on using tickets.