delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2007/11/05/09:50:00

X-Recipient: archive-cygwin AT delorie DOT com
X-Spam-Check-By: sourceware.org
Message-ID: <ba40711f0711050649g3276b097yb88ae247b1cfdc29@mail.gmail.com>
Date: Mon, 5 Nov 2007 09:49:23 -0500
From: "Lev Bishop" <lev DOT bishop AT gmail DOT com>
To: cygwin AT cygwin DOT com
Subject: Re: cygwin stable and cvs snapshot - fork() bug
In-Reply-To: <ba40711f0711050443h6733c234o3c2d4a78f410360d@mail.gmail.com>
MIME-Version: 1.0
References: <C0ED6A2866953E4487135B5DFCFF89A501C04512 AT hmsx21 DOT pnet DOT ch> <C0ED6A2866953E4487135B5DFCFF89A501C048D6 AT hmsx21 DOT pnet DOT ch> <20071029083512 DOT GA4224 AT calimero DOT vinschen DOT de> <C0ED6A2866953E4487135B5DFCFF89A501C04A65 AT hmsx21 DOT pnet DOT ch> <4725D656 DOT 5090303 AT cygwin DOT com> <C0ED6A2866953E4487135B5DFCFF89A501C375CD AT hmsx21 DOT pnet DOT ch> <ba40711f0710311126m6ae84f5ci4e7e481869ed63a7 AT mail DOT gmail DOT com> <20071101095835 DOT GG31224 AT calimero DOT vinschen DOT de> <20071105102147 DOT GI31224 AT calimero DOT vinschen DOT de> <ba40711f0711050443h6733c234o3c2d4a78f410360d AT mail DOT gmail DOT com>
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Unsubscribe: <mailto:cygwin-unsubscribe-archive-cygwin=delorie DOT com AT cygwin DOT com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
X-MIME-Autoconverted: from quoted-printable to 8bit by delorie.com id lA5EncTe029411

On 11/5/07, Lev Bishop wrote:
> 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.

It indeed seems this is behaviour not described in SuSv3. But several
unices support (some variant of) this behaviour. At least linux,
freebsd, hp-ux, solaris 10 mention it in their man pages, and openbsd
and netbsd seem to implement it that way even though they don't
describe it in the man pages.

FreeBSD:
     IPC_RMID     Removes the segment from the system.  The removal will not
                  take effect until all processes having attached the segment
                  have exited; however, once the IPC_RMID operation has taken
                  place, no further processes will be allowed to attach the
                  segment.  For the operation to succeed, the calling
                  process's effective uid must match shm_perm.uid or
                  shm_perm.cuid, or the process must have superuser privi-
                  leges.

HP-UX:
IPC_RMID	 	
Remove the shared memory identifier specified by shmid from the system
and destroy the shared memory segment and data structure associated
with it. If the segment is attached to one or more processes, then the
segment key is changed to IPC_PRIVATE and the segment is marked
removed. The segment disappears when the last attached process
detaches it. This cmd can only be executed by a process that has an
effective user ID equal to either that of a user with appropriate
privileges or to the value of either shm_perm.uid or shm_perm.cuid in
the data structure associated with shmid.

Solaris 10:
IPC_RMID
Remove the shared memory identifier specified by shmid from the
system. The segment referenced by the identifier will be destroyed
when all processes with the segment attached have either detached the
segment or exited. If the segment is not attached to any process when
IPC_RMID is invoked, it will be destroyed immediately. This command
can be executed only by a process that has appropriate privileges or
an effective user ID equal to the value of shm_perm.cuid or
shm_perm.uid in the data structure associated with shmid.

A further linux extension: In addition to all the above, Linux goes
even further and still allows you to attach the segment even after
marking it for deletion. Linux man page:
       Linux  permits  a  process  to attach (shmat()) a shared memory segment
       that has already been marked for deletion using shmctl(IPC_RMID).  This
       feature is not available on other Unix implementations; portable appliā
       cations should avoid relying on it.
Vmware and opera seem to depend on this extension-to-an-extension.
Freebsd (since version 5.2) has a sysctl kern.ipc.shm_allow_removed
which seems to allow you to force the linux behaviour on this issue.
Openbsd automatically does it (only) when running linux binaries via
compat_linux(8).

If you do implement the behaviour of not destroying the segment until
shm_nattach==0, you'll want to make sure that the shared memory key
can be reused immediately after the old segment has been IPC_RMIDed,
even though the old mapping may still be around. The other OS's which
implement it seem to do this by having shmctl(IPC_RMID) change the key
of the segment to be IPC_PRIVATE.

A cygwin discussion of not being able to reuse a shmid after
shmctl(IPC_RMID) is here:
http://www.cygwin.com/ml/cygwin/2001-11/msg01446.html
It looks like the old cygipc tried to implement the linux behaviour.

Don't you just love standards....

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/


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019