Subject: cygwin 1.3.10 fork+sockets+shmat/mmap=recreate_mmaps_after_fork_failed
From: Michael Potter <[email-masked]>
To: [email-masked]
Date: Sun, 2 Jun 2002 22:32:34 -0500

A sample program is below which demonstrats bug when fork, sockets
and (shmat or mmap) are used together.  The result is
recreate_mmaps_after_fork_failed error, which has been reported
under different circumstances.

The following is a sample run of that program:

------------------------------------------------------------
[@TERMSERV]/cygdrive/c/apps/apwin1/src/forktest>
-> ipcs

---------- Shared Memory Segments --------
     shmid     key       bytes     nattch    status

---------- Semaphore Arrays --------
     semid     nsems     key

---------- Message Queues --------
     msqid     used-bytes  messages

[@TERMSERV]/cygdrive/c/apps/apwin1/src/forktest>
-> gcc -oforktest forktest.c -lcygipc
[@TERMSERV]/cygdrive/c/apps/apwin1/src/forktest>
-> ./forktest
in pid = 2992
[@TERMSERV]/cygdrive/c/apps/apwin1/src/forktest>
-> b4 memset3
after memset3
entering NetWorkSocketPort=10210, Socket=5, sinport=57895exiting NetWorkSocketin
 pid = 2460
   2065 [main] forktest 3508 fixup_mmaps_after_fork: base address fails to match
 requested address 0x650000
c:\apps\apwin1\src\forktest\forktest.exe: *** recreate_mmaps_after_fork_failed

[@TERMSERV]/cygdrive/c/apps/apwin1/src/forktest>
-> ipcs

---------- Shared Memory Segments --------
     shmid     key       bytes     nattch    status
_shm 11392     502       1048576   0

---------- Semaphore Arrays --------
     semid     nsems     key

---------- Message Queues --------
     msqid     used-bytes  messages

[@TERMSERV]/cygdrive/c/apps/apwin1/src/forktest>
-> ipcrm shm 11392
[@TERMSERV]/cygdrive/c/apps/apwin1/src/forktest>
-> strace -f ./forktest 2>&1 >forktest.strace 2>&1
c:\apps\apwin1\src\forktest\forktest.exe: *** recreate_mmaps_after_fork_failed
[@TERMSERV]/cygdrive/c/apps/apwin1/src/forktest>
-> gtar -cf forktest.tar forktest.c forktest.strace
bash: gtar: command not found
[@TERMSERV]/cygdrive/c/apps/apwin1/src/forktest>
-> tar -cf forktest.tar forktest.c forktest.strace
[@TERMSERV]/cygdrive/c/apps/apwin1/src/forktest>
->

[@TERMSERV]/usr/local/lib>
-> ls -l libcygipc.a
-rw-r--r--    1 apwin1   Administ    26912 May 23 13:04 libcygipc.a
[@TERMSERV]/usr/local/lib>
-> cd ../../lib
[@TERMSERV]/usr/lib>
-> ls -l libcygwin.a
-rw-r--r--    1 apwin1   Administ   792112 Feb 25 10:16 libcygwin.a
[@TERMSERV]/usr/lib>
->

[@TERMSERV]/cygdrive/c/apps/cygwin/bin>
-> uname -a
CYGWIN_NT-5.0 TERMSERV 1.3.10(0.51/3/2) 2002-02-25 11:14 i686 unknown
[@TERMSERV]/cygdrive/c/apps/cygwin/bin>
->
------------------------------------------------------------

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>

static int RegProcNet_sd;
static struct sockaddr_in Sin;
static const int on = 1;

int SwitchToPrivate_sd(void)
{
   int NewNet_sd;
   unsigned long SizeOfsockaddr_in = sizeof (struct sockaddr_in);

   NewNet_sd = accept(RegProcNet_sd, (struct sockaddr *)&Sin,
    (size_t *)&SizeOfsockaddr_in);

   if (NewNet_sd < 0)
   {
      int SaveErrNo = errno;
      printf("Exiting due to error in accept %d", SaveErrNo);
      exit(1);
   }
   return(NewNet_sd);
}

void NetWorkSocket(void)
{

   int SizeOfsockaddr_in = sizeof (struct sockaddr_in);
   bzero((char *) &Sin, sizeof(Sin));
   Sin.sin_family = AF_INET; 
   Sin.sin_addr.s_addr = htonl(INADDR_ANY) ;
   Sin.sin_port = htons((unsigned short)10210);

   printf("entering NetWorkSocket");

   RegProcNet_sd = socket(AF_INET, SOCK_STREAM, 0);
   if (RegProcNet_sd < 0)
   {
      int SaveErrNo = errno;
      printf("Exiting due to error in socket %d", SaveErrNo);
      exit(1);
   }
   
   (void) setsockopt(RegProcNet_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
   
   if (bind(RegProcNet_sd, (struct sockaddr *)&Sin, SizeOfsockaddr_in) < 0)
   {
      int SaveErrNo = errno;
      printf("Exiting due to error in bind %d", SaveErrNo);
      exit(1);
   }

   if (listen(RegProcNet_sd, 1) < 0)
   {
      int SaveErrNo = errno;
      printf("Exiting due to error in listen %d", SaveErrNo);
      exit(1);
   }
   {
      printf("Port=%d, Socket=%d, sinport=%d",
                              10210, RegProcNet_sd, Sin.sin_port);
   }
   printf("exiting NetWorkSocket");
   return;
}

int main(int argc, char *argv[])
{
   char *shmptr3;
   int shmid3;
   int SaveErrno;
   int sd;

   if (fork())
   {
      printf("in pid = %d\n", getpid());
      exit(0);
   }

   shmid3 = shmget(502, 1024*1024, 0666|IPC_CREAT|IPC_EXCL);

   shmptr3 = (char *)shmat(shmid3, (void *)0, (int)0);
   printf("b4 memset3\n");
   memset(shmptr3, 0, 1024*1024);
   printf("after memset3\n");

   NetWorkSocket();

   sd = SwitchToPrivate_sd();

   fork();
   printf("in pid = %d\n", getpid());
   exit(0);
}

------------------------------------------------------------

Note: The program does an accept(), so you must telnet to port 10210
to allow the program to continue.

Any help is appreciated.

Thank you for providing/working on a great piece of software.

--
Michael Potter
[email-masked]

-- 
potter

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/