X-Recipient: archive-cygwin@delorie.com
X-SWARE-Spam-Status: No, hits=-3.5 required=5.0	tests=BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL,T_RP_MATCHES_RCVD
X-Spam-Check-By: sourceware.org
From: Lenci Damien <dlenci@sopragroup.com>
To: "cygwin@cygwin.com" <cygwin@cygwin.com>
Subject: Re: problem with fork() and temp dlls
Date: Fri, 29 Jun 2012 09:56:49 +0000
Message-ID: <7925_1340963812_4FED7BE3_7925_5434_2_B03025C959FD1A4796D42DC68C9C0823046C652B@wancyexmbx01.ancy.fr.sopra>
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Mailing-List: contact cygwin-help@cygwin.com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe@cygwin.com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin@cygwin.com>
List-Help: <mailto:cygwin-help@cygwin.com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner@cygwin.com
Mail-Followup-To: cygwin@cygwin.com
Delivered-To: mailing list cygwin@cygwin.com
Content-Transfer-Encoding: 8bit
X-MIME-Autoconverted: from quoted-printable to 8bit by delorie.com id q5T9vFad024344

> Looks like fork problems to me.  Perhaps you need to rebase the DLLs you're
> building?  See the link below for more info:

I've already done that, sorry I should have mentioned it.
I made a simple testcase reproducing the module loading algorithm of nagios :

File mydll.c is only:
int testvar = 42;


Compiled with :
gcc -shared -o mydll.dll mydll.c


File mymain.c :
 
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <stdlib.h>

int main (void){

        char output_file[80];
        int dest_fd;
        int source_file;
        void *buf;
        struct stat st;

        void *dllhandle;
        int *testvar;

        snprintf(output_file, sizeof(output_file) - 1, "nebmodXXXXXX");
        dest_fd = mkstemp(output_file);
        source_file = open("mydll.dll",O_RDONLY, 0644);

        fstat(source_file, &st);
        int buf_size = st.st_size;
        buf = malloc(buf_size);

        read( source_file, buf, buf_size);
        write(dest_fd, buf, buf_size);

        free(buf);

        fchmod(dest_fd, S_IRWXU);
        close(dest_fd);
        dllhandle = dlopen(output_file, RTLD_NOW | RTLD_GLOBAL);

        if (dllhandle == NULL) {
                printf("Unable to load dll : %s\n", dlerror());
                return 1;
        }

        unlink(output_file);

        if (fork()){
                testvar = (int *)dlsym(dllhandle, "testvar");
                printf("parent : %d\n", *testvar);
        }
        else{
                testvar = (int *)dlsym(dllhandle, "testvar");
                printf("child : %d\n", *testvar);
        }

}

Compiled with :
gcc -o mymain mymain.c

If I run this I got :
$ ./mymain.exe
      0 [main] mymain 6040 child_info_fork::abort: unable to map XXXXXX\tmp\dllforktest\nebmod5Ix5re, Win32 error 126
parent : 42

If I change the dlopen to load the original dll:
dllhandle = dlopen("mydll.dll", RTLD_NOW | RTLD_GLOBAL);

It works fine...

That means fork() try to reload the dll from file while it is already loaded by the parent process and I'm wondering why.
Is it a normal and wanted behavior? (don't think so, it works fine on debian)
Is it not wanted but normal (windows restriction maybe)?
Or is it some kind of bug in the fork implementation?

Thanks,

Damien Lenci

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


