Unexplained Linux System V IPC Shared Memory Segment Designated for Destruction
I have a Linux System V IPC shared memory segment that is being populated by one process and read by many others. All processes use an interface for a shared memory segment in the form of a class that takes care of finding, attaching, and detaching to the segment as part of its constructor / destructor methods.
The problem here is that from time to time I see a segment "split". I mean by looking at the output of "ipcs -m -s" I can see that I have two segments, one that has been marked for destruction but still has some processes associated with it, and the other one that has gotten all new attempts to connect to the segment. However, I never ask the kernel to destroy the segment. What's going on here ?!
Another thing to note is that, unfortunately, the system that this system runs on is seriously lagging behind in the memory department. There is 1GB of physical memory, no swap, and the Committed_AS in / proc / meminfo reports 2.5GB of memory. Luckily the system processes don't actually use this large memory ... they just ask for it (I still have about 660MB of "free" memory reported by vmstat). While I know this is far from ideal, there is nothing I can do about overloaded memory yet. However, looking at the kernel / libc source, I don't see anything there that will mark the shared memory segment for deletion for any reason other than a user request (but I may have missed it there, somewhere there).
For reference, here's the constructor for the shared memory interface class:
const char* shm_ftok_pathname = "/usr/bin";
int shm_ftok_proj_id = 21;
// creates a key from a file path so different processes will get same key
key_t m_shm_key = ftok(shm_ftok_pathname, shm_ftok_proj_id);
if ( m_shm_key == -1 )
{
fprintf(stderr,"Couldn't get the key for the shared memory\n%s\n",strerror(errno));
exit ( status );
}
m_shm_id = shmget(m_shm_key, sizeof(shm_data_s), (IPC_CREAT | 0666));
if (m_shm_id < 0)
{
fprintf(stderr,"Couldn't get the shared memory ID\nerrno = %s \n",strerror(errno));
exit ( status );
}
// get a ptr to shared memory, which is a shared mem struct
// second arg of 0 says let OS choose shm address
m_shm_data_ptr = (shm_data_s *)shmat(m_shm_id, 0, 0);
if ( (int)m_shm_data_ptr == -1 )
{
fprintf(stderr,"Couldn't get the shared memory pointer\n");
exit ( status );
}
And here is my uname output: Linux 2.6.18-5-686 # 1 SMP Fri Jun 1 00:47:00 UTC 2007 i686 GNU / Linux
source to share