[Boost-bugs] [Boost C++ Libraries] #8276: Shared Memory Access by 32-bit and 64-bit Processes

Subject: [Boost-bugs] [Boost C++ Libraries] #8276: Shared Memory Access by 32-bit and 64-bit Processes
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-03-11 17:12:17

#8276: Shared Memory Access by 32-bit and 64-bit Processes
 Reporter: Bob Stevens <bob@…> | Owner: igaztanaga
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: interprocess
  Version: Boost 1.52.0 | Severity: Showstopper
 Keywords: 32Bit,64Bit |
 Problem: Exception raised in Segment.find_or_construct<>() call.
 Problem: Exception raised in Segment.find_or_construct<>() call.

 The system operates if all of the the processes are 64-bit, or if all of
 the processes are 32-bit.

 If the shared memory segment has been constructed by a 64-bit process,
 attempting to find_or_construct it with a 32-bit process fails. Similary,
 if the shared memory segment has been constructed by a 32-bit process,
 attempting to find_of_construct it with a 64-bit process fails.

 I have determined that the actual objects in shared memory report
 different sizes when compiled for 32-bit or 64-bit.

 This is a multi-cast PubSub program. It constructs the following complex
 data structure in shared memory:

     // Boost includes
     #include <boost\interprocess\managed_shared_memory.hpp>
     #include <boost\interprocess\containers\map.hpp>
     #include <boost\unordered_map.hpp>
     #include <boost\interprocess\allocators\allocator.hpp>
     #include <boost\interprocess\containers\vector.hpp>
     #include <boost\interprocess\containers\string.hpp>
     #include <boost\interprocess\sync\interprocess_mutex.hpp>
     #include <boost\interprocess\sync\interprocess_semaphore.hpp>
     #include <boost\interprocess\sync\scoped_lock.hpp>
     #include <boost\interprocess\detail\move.hpp>
     #include <boost\thread.hpp>
     #include <boost\foreach.hpp>
     #include <boost\format.hpp>
     #include <functional>
     #include <boost/functional/hash.hpp>

     typedef managed_shared_memory::segment_manager
 segment_manager_t; // this is the segment_manager

     // Define the allocators.
     typedef boost::interprocess::allocator<void, segment_manager_t>
 void_allocator; // void_allocator is convertible to any other
     typedef boost::interprocess::allocator<int, segment_manager_t>
 int_allocator; // allocator for allocating ints.
     typedef boost::interprocess::vector<int, int_allocator>
 int_vector; // an int_vector is a vector of ints.
     typedef boost::interprocess::allocator<int_vector, segment_manager_t>
 int_vector_allocator; // an allocator for allocating vectors of ints.
     typedef boost::interprocess::vector<int_vector, int_vector_allocator>
 int_vector_vector; // an int_vector_vector is a vecctor of (vectors
 of ints)
     typedef boost::interprocess::allocator<interprocess_semaphore,
 segment_manager_t> semaphore_allocator; // an allocator for
     typedef boost::interprocess::allocator<WCHAR, segment_manager_t>
 wchar_allocator; // an allocator for wide chars.
     typedef boost::interprocess::basic_string<WCHAR,
 std::char_traits<WCHAR>, wchar_allocator> wchar_string; // a
 basic_string (which supports formatting). This is built on a collection
 of wide chars, allocated by wchar_alloctor.

     class EventMessage {
         EnumEventType EventType_; // an enum
         EnumEventSubType EventSubType; // an enum
         ULONG32 ProcessId_;
         ULONG32 ThreadId_;
         EnumMyType MyType_; // an enum
         wchar_string FullPath_;
         GUID GuidPublisher_;

     // Event allocators
     typedef boost::interprocess::allocator<EventMessage,
 segment_manager_t> EventMessage_allocator; // allocator for
 allocating EventMessage
     typedef boost::interprocess::vector<EventMessage,
 EventMessage_allocator> EventMessage_vector; // vector of
 EventMessage objects.

     class Subscription {
         ULONG32 uSignature_;
         ULONG32 uSubscribingProcessId_;
         ULONG32 uSubscribingThreadId_;
         EnumEventType nEventType_ // an enum
         offset_ptr<interprocess_semaphore> pSemaphoreSubscription_;
         GUID guidSubscriber_;
         BOOL fDestructed;
         BOOL fWaiting_;
         BOOL fCancelled_;
         EventMessage_vector events_; // a shared memory vector of

     // Define the types related to Subscription
     typedef boost::interprocess::allocator<Subscription,
 segment_manager_t> subscription_allocator; //
 allocator for allocating Subscription
     typedef boost::interprocess::allocator<GUID, segment_manager_t>
 guid_allocator; // allocator for allocating GUID
     typedef std::pair<const GUID, Subscription>
 pair_guid_subscription; // a pair of GUID, Subscription
     typedef boost::interprocess::allocator<EnumEventType,
 segment_manager_t> eventtype_allocator; // allocator
 for allocating EnumEventType
     typedef boost::interprocess::allocator<pair_guid_subscription,
 segment_manager_t> pair_guid_subscription_allocator; //
 allocator for pair_guid_subscription
     typedef boost::unordered_map<GUID, Subscription, boost::hash<GUID>,
 std::equal_to<GUID>, pair_guid_subscription_allocator>
 guid_subscription_map; // a map of GUID => Subscription
     typedef std::pair<const EnumEventType, guid_subscription_map>
 pair_eventtype_pair_guid_subscription; // a pair(EnumEventType,
 pair(GUID, Subscription))
 segment_manager_t> pair_eventtype_pair_guid_subscription_allocator; //
 allocator for pair(EnumEventType, pair(GUID, Subscription))
     typedef boost::unordered_map<EnumEventType, guid_subscription_map,
 boost::hash<int>, std::equal_to<int>,
 eventtype_map_guid_subscription_map; // a map(EnumEventType, map<GUID,
     typedef boost::interprocess::vector<Subscription,
 subscription_allocator> subscription_vector; // a
 vector of Subscriptions
     typedef boost::interprocess::allocator<subscription_vector,
 segment_manager_t> subscription_vector_allocator; //
 allocator for allocating a vector of Subscription.
     typedef boost::interprocess::allocator<guid_subscription_map,
 segment_manager_t> guid_subscription_map_allocator; //
 allocator for allocating a map of GUID => Subscription
 segment_manager_t> eventtype_map_guid_subscription_map_allocator; //
 allocator for allocating map<EnumEventType, map<GUID, Subscription>>

     // This is the single item defined in the segment
     class Base {
         uint64_t reserved1_;
         uint64_t reserved2_;
         ULONG32 uSignature_;
         interprocess_mutex mutexSharedMemory_
         eventtype_map_guid_subscription_map subscriptions_; // a shared
 memory map of [GUID, Subscription] (the active subscriptions)

 The following sizes are reported:
     sizeof(IntPtr): 8
     sizeof(ULONG32): 4
     sizeof(BOOL): 4
     sizeof(EnumEventType): 4
     sizeof(EnumEventSubType): 4
     sizeof(EnumCloudAppIconBadgeType): 4
     sizeof(GUID): 16
     sizeof(EventMessage): 72
     sizeof(Subscription): 88
     sizeof(Base): 104
     sizeof(size_t): 8

     sizeof(IntPtr): 4
     sizeof(ULONG32): 4
     sizeof(BOOL): 4
     sizeof(EnumEventType): 4
     sizeof(EnumEventSubType): 4
     sizeof(EnumCloudAppIconBadgeType): 4
     sizeof(GUID): 16
     sizeof(EventMessage): 60
     sizeof(Subscription): 64
     sizeof(Base): 72
     sizeof(size_t): 4

 Note that all of the fundamental types are the same size, but the Boost
 interprocess sizes are different.

 I thought that as of Boost 1.48 all of the sizes were normalized to use
 the same shared memory sizes whether compiled for 32- or 64-bit.

 Perhaps I am doing something wrong. Suggestions will be welcome. Thanks.


Ticket URL: <https://svn.boost.org/trac/boost/ticket/8276>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:12 UTC