cygwin stable and cvs snapshot - fork() bug

Lev Bishop lev.bishop@gmail.com
Mon Nov 5 12:43:00 GMT 2007


On 11/5/07, Corinna Vinschen  wrote:
> On Nov  1 10:58, Corinna Vinschen wrote:
> > On Oct 31 14:26, Lev Bishop wrote:
> > > $ cat lev.c && gcc -o lev lev.c -Wall -Wextra && CYGWIN=server ./lev
> > > #include <stdio.h>
> > > #include <unistd.h>
> > > #include <sys/shm.h>
> > >
> > > int main(void)
> > > {
> > >         int shmid;
> > >         if ((shmid = shmget(IPC_PRIVATE, 100,IPC_CREAT | 0600 )) < 0 ||
> > >                 !shmat(shmid, NULL, 0) ||
> > >                 shmctl(shmid, IPC_RMID, NULL) < 0)
> > >                 puts("problems with shm!");
> > >         fork();
> > > }
> > > lev.c: In function `main':
> > > lev.c:13: warning: control reaches end of non-void function
> > >       3 [main] lev 1924 c:\Documents and
> > > Settings\Lev\Desktop\mpd-0.13.0\lev.exe: *** fatal error -
> > > MapViewOfFileEx (0x3E0000), Win32 error 6.  Terminating.
> > >     124 [main] lev 5076 fork: child 1924 - died waiting for dll
> > > loading, errno 11
> >
> > Thanks for the testcase.  I'm surprised that nobody experienced this
> > problem before.  Sorta holiday here, so I'll look into it next week.
>
> Ouch, ouch, ouch.  shmctl(IPC_RMID) closed the handle to the shared
> memory, but neglected to remove the actual mappings as well as the
> bookkeeping structure.  The result is that after a fork the child thinks
> there are still mappings which have to be duplicated into its own
> memory.  But the handle has already been closed in the parent, so the
> MapViewOfFile call fails with "invalid handle".
>
> Unfortunately not many applications use shmctl(IPC_RMID) before creating
> a child process since usually the shared memory is meant to be... well,
> shared.  That's why this didn't crop up more often, obviously.

Are you sure that you're interpreting IPC_RMID correctly? My
understanding is that you can still share the memory until you
actually remove the mapping. (Sort of like how you can unlink() a temp
file immediately after you open it, and continue to use it). I assumed
this was the reason for the create-map-remove pattern used by mpd.

From the linux man page:
       IPC_RMID    Mark the segment to be destroyed.  The  segment  will  only
                   actually  be  destroyed  after the last process detaches it
                   (i.e., when the shm_nattch member of the associated  strucâ
                   ture  shmid_ds  is  zero).  The caller must be the owner or
                   creator, or be privileged.  If a segment  has  been  marked
                   for  destruction,  then the (non-standard) SHM_DEST flag of
                   the shm_perm.mode field in the  associated  data  structure
                   retrieved by IPC_STAT will be set.

Lev

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/



More information about the Cygwin mailing list