Interprocess container segmentation fault (example provided)

I'm running into issues with using interprocess containers have other containers added to them during runtime. A very high level description is I have a set of data structures in shared memory that can be accessed and modified by more than one process. I'm creating the data structures in the first process and storing the name of the segment within the data structure. Methods that modify the data by adding another container first lookup the segment using its name, build the new container, and then insert it into the existing container. In the example I'm providing below, I have a map of lists. For some reason, when I add a new list, if I open the segment by name, and allocate the list using the segment manager returned via the lookup, the list isn't initialized correctly and accessing the list (via printData here) results in a segfault. However, if I bypass the segment lookup and just cache the raw pointer to the segment, it works. It's probably easiest just to look at the code below. In addMessage, you can see how I'm trying to initialize the list in a manner that will work across multiple processes. This breaks. Commented out directly below it is a hack that will work. I can't see any reason why one works and the other doesn't. The "managed_shared_memory" object returned from the lookup appears to be valid and exactly the same as the pointer I'm caching with the data structure in this example.
I am currently using 1.49 final, but I've observed similar behavior in other 1.4x releases.
=================================BEGIN CODE====================================================
#include

El 01/03/2012 19:01, Davidson, Josh escribió:
I'm running into issues with using interprocess containers have other containers added to them during runtime. A very high level description is I have a set of data structures in shared memory that can be accessed and modified by more than one process. I'm creating the data structures in the first process and storing the name of the segment within the data structure. Methods that modify the data by adding another container first lookup the segment using its name, build the new container, and then insert it into the existing container. In the example I'm providing below, I have a map of lists. For some reason, when I add a new list, if I open the segment by name, and allocate the list using the segment manager returned via the lookup, the list isn't initialized correctly and accessing the list (via printData here) results in a segfault. However, if I bypass the segment lookup and just cache the raw pointer to the segment, it works. It's probably easiest just to look at the code below. In addMessage, you can see how I'm trying to initialize the list in a manner that will work across multiple processes. This breaks. Commented out directly below it is a hack that will work. I can't see any reason why one works and the other doesn't. The "managed_shared_memory" object returned from the lookup appears to be valid and exactly the same as the pointer I'm caching with the data structure in this example.
I am currently using 1.49 final, but I've observed similar behavior in other 1.4x releases.
You are storing a *local* map that allocates memory in shared memory (that is, the internal pointers of the map are in the stack, whereas the allocated nodes are in shared memory), which is really a bad idea as once you unmap the segment, as the local map's internal pointers point to segmentation-fault friendly memory. I know that "managed_shared_memory shm" outlives "TestStore store" but the problem is that you open the shm again in "managed_shared_memory m" and that maps the shared memory *in another address, different to the address mapped by "managed_shared_memory shm"* (two views of the same shared memory, as you map a file twice). So you end up with a local map pointing to *two different address ranges* (although the share the same underlying shared memory object, just think it's like a file). Then you unmap "managed_shared_memory m" (the second address range disappears) and then when you try to iterate, when the local map tries to read an element through the second address range, you get a segmentation fault. If you put the map itself in shared memory (e.g. use a named construct) you can avoid the problem. And if you have already mapped the shared memory once, avoid wasting OS resources (the OS must synchronize the two address ranges in the same process with the same underlying device/shm/mapped file) and application address space mapping the same shared memory/file several times. Sometimes is useful to open the shared memory segment more than once from the same process (say, when you communicate a DLL with an application, or when trying to implement a intermodule singleton type), but in general, try to avoid this. Best, Ion
participants (2)
-
Davidson, Josh
-
Ion Gaztañaga