Bugzilla – Bug 2218
Old shared memory base address not removed from based pointer repository when segment is remapped to new base address
Last modified: 2005-08-29 04:31:58
You need to log in before you can comment on or make changes to this bug.
When an ACE_MMAP_Memory_Pool memory segment base address is moved due to a remapping operation, the ACE_Based_Pointer_Repository is updated with the new base address, but the old mapping is not removed. The following test demonstrates the issue: typedef ACE_Malloc_T< ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_PI_Control_Block > MMAP_PI_Allocator; // Check that MMAP memory blocks are correctly remapped // into the Based_Pointer_Repository // (i.e. when a segment is resized it may move its base address // because the OS cannot fit the new segment size at the same // base address, in this case the Repository must be updated) // (see http://deuce.doc.wustl.edu/bugzilla/show_bug.cgi?id=2216) int mmap_remap_test(void) { // Use a Position Independent memory segment // because this one is going to move MMAP_PI_Allocator* alloc; // Make sure the Pool options are set to allow // the segment to move ACE_MMAP_Memory_Pool_Options data_opts( 0, ACE_MMAP_Memory_Pool_Options::NEVER_FIXED); ACE_OS::unlink("foo"); ACE_NEW_RETURN (alloc, MMAP_PI_Allocator ("foo", "foo", &data_opts), -1); // cause memory segment to grow until it is forced // to be remapped at different base address size_t size = 4096; void* bar = 0; void* oba = alloc->base_addr(); while(oba == alloc->base_addr()) { bar = alloc->malloc(size); size += size; } void* nba = alloc->base_addr(); void* ba; if(ACE_BASED_POINTER_REPOSITORY::instance()->find(nba, ba) == -1) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Unable to find base address after remap of segment\n"))); alloc->remove(); delete alloc; return -1; } if(ba != nba) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("New base address not mapped after MMAP remap\n"))); alloc->remove(); delete alloc; return -1; } // Check old base address has been removed // from the repository if(ACE_BASED_POINTER_REPOSITORY::instance()->find(oba, ba) == -1) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Unable to find base address after remap of segment\n"))); alloc->remove(); delete alloc; return -1; } if(ba) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Old base address no removed after MMAP remap\n"))); alloc->remove(); delete alloc; return -1; } alloc->remove(); delete alloc; return 0; } I have added this test to the test program I wrote for: http://deuce.doc.wustl.edu/bugzilla/show_bug.cgi?id=1991
This bug is dependent on 1991
Proposed fix attached, when a segment is remapped, the base address before the remap is compared to the base address after the remap. If the base address has changed, the old base address is unbound from the Based_Pointer_Repository before the new address and size are bound.
Created an attachment (id=371) [details] Patch to file MMAP_Memory_pool.cpp for proposed fix
Mon Aug 29 09:31:12 UTC 2005 Johnny Willemsen <jwillemsen@remedy.nl> * ace/MMAP_Memory_Pool.cpp: Fixed bugzilla bug 2218, when an ACE_MMAP_Memory_Pool memory segment base address is moved due to a remapping operation, the ACE_Based_Pointer_Repository is updated with the new base address, but the old mapping was not removed. Thanks to Steve Williams <steve at telxio dot com> for reporting this and supplying the fix and regression test below.