Subject: Re: "panic: trap" while trying to run linux/i386 netscape with
To: None <s_frueau@ira.uka.de>
From: Lennart Augustsson <augustss@cs.chalmers.se>
List: current-users
Date: 12/16/1998 02:22:05
As far as I can tell the linux emulation is broken.
netscape dies in bsd_to_linux_wstat because *status
is -1.  A quick glance at the code seems to reveal
that WSTOPSIG returns the upper 24 bits.  The code
does a shift that should have produced -1, but maybe
there is an egcs codegen bug?

Furthermore, the indexing in bsd_to_linux_wstat should,
in my opinion, be guarded by some tests to make sure
that 0 <= *status < NSIG.

There is yet another bug (but harmless):
in linux_sys_wait4 status is assigned a pointer that points
to an object of size sizeof(int *) instead of size sizeof(int).

That's all the bugs it could spot in 5 minutes.

       -- Lennart


void
bsd_to_linux_wstat(status)
	int *status;
{

	if (WIFSIGNALED(*status))
		*status = (*status & ~0177) |
		    native_to_linux_sig[WTERMSIG(*status)];
	else if (WIFSTOPPED(*status))
		*status = (*status & ~0xff00) |
		    (native_to_linux_sig[WSTOPSIG(*status)] << 8);
}

/*
 * This is very much the same as waitpid()
 */
int
linux_sys_wait4(p, v, retval)
	struct proc *p;
	void *v;
	register_t *retval;
{
	struct linux_sys_wait4_args /* {
		syscallarg(int) pid;
		syscallarg(int *) status;
		syscallarg(int) options;
		syscallarg(struct rusage *) rusage;
	} */ *uap = v;
	struct sys_wait4_args w4a;
	int error, *status, tstat;
	caddr_t sg;

	if (SCARG(uap, status) != NULL) {
		sg = stackgap_init(p->p_emul);
		status = (int *) stackgap_alloc(&sg, sizeof status);
	} else
		status = NULL;

	SCARG(&w4a, pid) = SCARG(uap, pid);
	SCARG(&w4a, status) = status;
	SCARG(&w4a, options) = SCARG(uap, options);
	SCARG(&w4a, rusage) = SCARG(uap, rusage);

	if ((error = sys_wait4(p, &w4a, retval)))
		return error;

	sigdelset(&p->p_siglist, SIGCHLD);

	if (status != NULL) {
		if ((error = copyin(status, &tstat, sizeof tstat)))
			return error;

		bsd_to_linux_wstat(&tstat);
		return copyout(&tstat, SCARG(uap, status), sizeof tstat);
	}

	return 0;
}