[interprocess] shared memory map only working with built-in types?

Hello Ion, Title says it all really: the attached mini-program gives me a segmentation fault on ubuntu linux 8.04 with gcc 4.2.3 when trying to read back the shared memory between process invocations (trying a similar program on XP also fails). If the comments on lines 33/34 and 66-67/68-69 are swapped it works as expected. I've also tried and failed to get it working with my own types as well as std::string. Most of the interprocess tests work fine on my system* so I wonder if it's not possible to use UDTs with this sort of shared memory? I couldn't find anything in the docs (so far) that suggests what I'm doing is silly/wrong. Another minor problem I'm getting is that shm_unlink isn't found by default; adding <library>/boost/thread/ to the dependencies in my Jamfile gets around this, but I'm not sure what the 'correct' way of fixing this is (do you want more info about this one?). Thanks for the library, it simplifies what I'm trying to do loads. :) Cheers, Darren [*] - named_condition_test.cpp fails because: """ ../../../boost/interprocess/sync/named_condition.hpp:165: error: 'external_unlock' was not declared in this scope """ ...and unodered_test.cpp fails because: """ ../../../boost/unordered_set.hpp:479: error: 'struct boost::unordered_detail::move_from<boost::unordered_multiset<int, boost::hash<int>, std::equal_to<int>, boost::interprocess::allocator<int, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0u>, boost::interprocess::iset_index>
' has no member named 'base'
<snip> unordered_test.cpp:29: instantiated from here ../../../boost/unordered_set.hpp:479: error: 'struct boost::unordered_detail::move_from<boost::unordered_multiset<int, boost::hash<int>, std::equal_to<int>, boost::interprocess::allocator<int, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0u>, boost::interprocess::iset_index>
' has no member named 'base' """

Darren Garvey wrote:
Hello Ion,
Title says it all really: the attached mini-program gives me a segmentation fault on ubuntu linux 8.04 with gcc 4.2.3 when trying to read back the shared memory between process invocations (trying a similar program on XP also fails). If the comments on lines 33/34 and 66-67/68-69 are swapped it works as expected. I've also tried and failed to get it working with my own types as well as std::string.
I haven't looked closely at the types in your program, but I believe shared memory can only be used with POD types. No types that have their own indirection to other data structures (such as virtual tables, or their own heap-allocated memory, such as std::string). This is because only the object's own address is remapped into different processes, but if they use pointers internally there are good chances they are only correct for one process (the one allocating the object). Regards, Stefan -- ...ich hab' noch einen Koffer in Berlin...

Hi Darren, On Sun, Jun 15, 2008 at 7:51 PM, Darren Garvey <darren.garvey@gmail.com> wrote:
Hello Ion,
Title says it all really: the attached mini-program gives me a segmentation fault on ubuntu linux 8.04 with gcc 4.2.3 when trying to read back the shared memory between process invocations (trying a similar program on XP also fails). If the comments on lines 33/34 and 66-67/68-69 are swapped it works as expected. I've also tried and failed to get it working with my own types as well as std::string.
I think you need to use the appropriate allocator with the STL types -- and I think if you need to use the appropriate shared memory allocators for the things you need to keep in the shared memory segment(s). I took a look at your code, and you may have to specialize the string's allocator to use the Interprocess allocator types. HTH. -- Dean Michael C. Berris Software Engineer, Friendster, Inc.

2008/6/15 Dean Michael Berris <mikhailberis@gmail.com>:
I took a look at your code, and you may have to specialize the string's allocator to use the Interprocess allocator types.
Aha, that sounds like what I was missing... I'll have to have a look again at the docs about the allocators. Cheers Dean, Darren

On 15/06/2008, Darren Garvey <darren.garvey@gmail.com> wrote:
...and unodered_test.cpp fails because: """ ../../../boost/unordered_set.hpp:479: error: 'struct boost::unordered_detail::move_from<boost::unordered_multiset<int, boost::hash<int>, std::equal_to<int>, boost::interprocess::allocator<int, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0u>, boost::interprocess::iset_index>
' has no member named 'base'
That's a bug in unordered_set. It should be fixed in trunk. Thanks. Ion, the attached patch is required to get the test to run on g++ 4.3, with the '--std=c++0x' flag. I think the explicit casts to 'void*' are required because the C++-0x std::pair has a template constructor - which is instantiated with the first argument as 'int' which can't be converted to 'void*'. Daniel

On 15/06/2008, Daniel James <daniel_james@fmail.co.uk> wrote:
Ion, the attached patch is required to get the test to run on g++ 4.3
Sorry, the patch isn't correct - I used boost::interprocess::detail::identity in boost::interprocess::forward, which is an identity function - probably not what you intended. Also, running the tests with '-std=c++0x', there are problems with calling 'move' and 'forward' unqualified, ADL is causing an ambiguous overload of 'boost::interprocess::move' and 'std::move'. Daniel

Daniel James wrote:
On 15/06/2008, Daniel James <daniel_james@fmail.co.uk> wrote:
Ion, the attached patch is required to get the test to run on g++ 4.3
Sorry, the patch isn't correct - I used boost::interprocess::detail::identity in boost::interprocess::forward, which is an identity function - probably not what you intended.
Also, running the tests with '-std=c++0x', there are problems with calling 'move' and 'forward' unqualified, ADL is causing an ambiguous overload of 'boost::interprocess::move' and 'std::move'.
Ok. I need to install gcc 4.3, and modify Interprocess to support std::move and remove boost::interprocess::move if rvalue references are present. But this will take some time :-(
Daniel
Regards, Ion

Darren Garvey wrote:
Hello Ion,
Title says it all really: the attached mini-program gives me a segmentation fault on ubuntu linux 8.04 with gcc 4.2.3 when trying to read back the shared memory between process invocations (trying a similar program on XP also fails).
The problem is that you are trying to put a type (std::string) that is not ready for shared memory or memory mapped files because: 1) it surely uses internal raw pointers 2) allocates memory from the heap instead of from the shared memory That's why Interprocess offers its own containers. See documentation about those containers and also try to see some tests where interprocess basic_string is being used. That will give you some clues on how to use strings in shared memory.
[*] - named_condition_test.cpp fails because: """ ../../../boost/interprocess/sync/named_condition.hpp:165: error: 'external_unlock' was not declared in this scope """
Thanks. Solved in trunk. Regards, Ion

Hi Ion, 2008/6/15 Ion Gaztañaga <igaztanaga@gmail.com>:
Darren Garvey wrote:
Hello Ion,
Title says it all really: the attached mini-program gives me a segmentation fault on ubuntu linux 8.04 with gcc 4.2.3 when trying to read back the shared memory between process invocations (trying a similar program on XP also fails).
The problem is that you are trying to put a type (std::string) that is not ready for shared memory or memory mapped files because:
1) it surely uses internal raw pointers 2) allocates memory from the heap instead of from the shared memory
That's why Interprocess offers its own containers. See documentation about those containers and also try to see some tests where interprocess basic_string is being used. That will give you some clues on how to use strings in shared memory.
It all works a charm with interprocess::basic_string<>. Great! I didn't notice that initially - even though I now see it's clearly documented in the header reference... Perhaps a quick mention of the supported containers from the "creating vectors/maps in shared memory" section would be helpful? Anyway, thanks for the pointers (no pun intended). Darren

Darren Garvey wrote:
It all works a charm with interprocess::basic_string<>. Great! I didn't notice that initially - even though I now see it's clearly documented in the header reference... Perhaps a quick mention of the supported containers from the "creating vectors/maps in shared memory" section would be helpful?
Nice to hear it. I'll add an example that creates a map holding strings to the "quick guide for the impatient", because it's one of the most repeated questions.
Anyway, thanks for the pointers (no pun intended).
Darren
Regards, Ion
participants (5)
-
Daniel James
-
Darren Garvey
-
Dean Michael Berris
-
Ion Gaztañaga
-
Stefan Seefeld