Hello,
Is it allowed to issue the fork() system call while not in the main
thread? When I read the OpenGroup specifications I don't seem to find
anything against allowing this.
In particular, if I create a thread, then issue a fork(), data that
exists on the stack is corrupted after the fork() is in the child. Using
data on the heap doesn't show any issues (and is currently my
workaround, in case this is a bug).
I've created a minimal example:
$ gcc -g -O0 forktestcase.c -o forktestcase.exe
$ ./forktest
Pointer BEFORE THE FORK env is 0x28cd00
This is the child
Pointer env is 0x28cd00
env[0] is
env[1] is
Child exited with 0
Further, a stackdump is now present, probably while iterating through
the null terminated array at 0x28cd00 after the fork().
If you have a look at the attached code, I believe the expected output is
$ ./forktest
Pointer BEFORE THE FORK env is 0x28cd00
This is the child
Pointer env is 0x28cd00
Child exited with 0
This bug is not recreatable if we execute fork() in the main thread and
not a separate thread.
Please find attached the test case.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
struct mydat {
pthread_t pth;
char **env;
pid_t pid;
int status;
};
extern char **environ;
void *callfunc(void *data)
{
struct mydat *dat = data;
int pid;
int i;
printf("Pointer BEFORE THE FORK env is %p\n", dat->env);
i = 0;
while (dat->env[i]) {
printf(" env[%d] is %s\n", i, dat->env[i]);
i++;
}
pid = fork();
if (pid == 0) {
int i;
printf("This is the child\n");
printf("Pointer env is %p\n", dat->env);
i = 0;
while (dat->env[i]) {
printf(" env[%d] is %s\n", i, dat->env[i]);
i++;
}
exit(0);
} else {
int status;
dat->pid = pid;
waitpid(pid, &status, 0);
dat->status = status;
printf("Child exited with %d\n", WEXITSTATUS(status));
}
}
void newthread(struct mydat *dat)
{
if (pthread_create(&dat->pth, NULL, callfunc, dat)) {
perror("Couldn't create thread\n");
return;
}
pthread_join(dat->pth, NULL);
}
int main(int argc, char **argv)
{
struct mydat *dat;
int value1;
int valueb1, valueb2;
int fd1, fd2;
char *env2[] = { "APPTESTRESULT=42", (char *)0 };
char *env[] = { (char *)0 };
dat = malloc(sizeof(struct mydat));
dat->env = env;
newthread(dat);
free(dat);
}--
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