Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems when using fork and vfork in linux_syscall implmented by zCore. #186

Open
Crayon-new opened this issue May 25, 2021 · 4 comments
Open

Comments

@Crayon-new
Copy link

We built a test case for fork(), but there are segment fault also for vfork(). Can anyone help me?

QQ图片20210525221156

@wangrunji0408
Copy link
Member

Fork is not supported in library OS mode now. Because user programs and libOS are running in a single Linux process, sharing the address space.

Instead vfork should work. Maybe there is an unknown bug here :(

@ruanych
Copy link

ruanych commented May 25, 2021

In my test, vfork also did not work properly.
vfork

I noticed that vfork is used in zCore\linux-syscall\testtestsem1.c and it can pass the test normally.

Is it because of this line of code?

 execl("/bin/testsem2", "/bin/testsem2", NULL);
testtestsem1.c
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 700
#endif
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/sem.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <stdio.h>

static const char path[] = ".";
static const int id = 's';

#define T(f) assert((f) != -1)

static void inc()
{
	time_t t;
	key_t k;
	int semid, semval, sempid, semncnt, semzcnt;
	struct semid_ds semid_ds;
	union semun {
		int val;
		struct semid_ds *buf;
		unsigned short *array;
	} arg;
	struct sembuf sops;

	T(t = time(0));
	T(k = ftok(path, id));

	/* make sure we get a clean semaphore id */
	T(semid = semget(k, 1, IPC_CREAT | 0666));
	T(semctl(semid, 0, IPC_RMID));
	T(semid = semget(k, 1, IPC_CREAT | IPC_EXCL | 0666));

	/* check IPC_EXCL */
	errno = 0;
	if (semget(k, 1, IPC_CREAT | IPC_EXCL | 0666) != -1 || errno != EEXIST)
		printf("semget(IPC_CREAT|IPC_EXCL) should have failed with EEXIST, got %s\n", strerror(errno));

	/* check if msgget initilaized the msqid_ds structure correctly */
	arg.buf = &semid_ds;
	T(semctl(semid, 0, IPC_STAT, arg));
	if (semid_ds.sem_ctime < t)
		printf("semid_ds.sem_ctime >= t failed: got %lld, want >= %lld\n", (long long)semid_ds.sem_ctime, (long long)t);
	if (semid_ds.sem_ctime > t + 5)
		printf("semid_ds.sem_ctime <= t+5 failed: got %lld, want <= %lld\n", (long long)semid_ds.sem_ctime, (long long)t + 5);

	/* test sem_op > 0 */
	sops.sem_num = 0;
	sops.sem_op = 1;
	sops.sem_flg = 0;
	T(semval = semctl(semid, 0, GETVAL));
	assert(semval == 0);
	T(semop(semid, &sops, 1));
	T(semval = semctl(semid, 0, GETVAL));
	assert(semval == 1);
	T(sempid = semctl(semid, 0, GETPID));
	assert(sempid == getpid());
	T(semncnt = semctl(semid, 0, GETNCNT));
	assert(semncnt == 0);
	T(semzcnt = semctl(semid, 0, GETZCNT));
	assert(semzcnt == 0);
}

int main(void)
{
	int p;
	int status;
	inc();
	int pid = vfork();
	if (pid < 0)
        printf("error in fork!\n");
    else if (pid == 0)
    {
        execl("/bin/testsem2", "/bin/testsem2", NULL);
        exit(0);
    }
	return 0;
}

@wangrunji0408
Copy link
Member

wangrunji0408 commented May 25, 2021

Oh you are right. According to the Linux manual:

The vfork() function has the same effect as
fork(2), except that the behavior is undefined if the process
created by vfork() either modifies any data other than a variable
of type pid_t used to store the return value from vfork(), or
returns from the function in which vfork() was called, or calls
any other function before successfully calling _exit(2) or one of
the exec(3) family of functions.

The child process should do nothing but call exec immediately.

@ruanych
Copy link

ruanych commented May 26, 2021

It's great! Thanks for your reply!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants