Boost logo

Boost Users :

Subject: Re: [Boost-users] Interprocess container segmentation fault (example provided)
From: Ion Gaztañaga (igaztanaga_at_[hidden])
Date: 2012-03-01 17:23:40


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


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net