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;
}