[uClibc]Re: vfork problem on SH port

Manuel Novoa III mnovoa3 at bellsouth.net
Fri Mar 16 14:49:37 UTC 2001


Jean-Yves,

On Thu, 15 Mar 2001, AVENARD,JEAN-YVES (HP-Australia,ex2) wrote:
> Dear Manuel and Erik
> 
> When running the sh (shell, not the processor) found in userland/sh on our
> SH platform, we are experiencing some problems when running applications.
> 
> Doing something like:
> > cat > /dev/ttySC0 < /dev/ttySC1 &
> > cat > /dev/ttySC1 < /dev/ttySC0 &
> [..] everything here works fine
> > ls
> 
> >From here, ls will display the content of the directory and we will never
> see the prompt back.
>
(stuff omitted)
>
> But I'm still puzzled (for some unknown reasons), and I remembered the
> problems you had with vfork on both ARM and i386 architecture.. What was
> wrong exactly ?
> Looking at your modification, you're just doing manually what the macro
> syscall is doing. You call the entry points 190 (vfork) and exit returning a
> value.
> 
> Is there anything I've missed ? The current vfork in my Hitachi-SH port is
> just a syscall to vfork using a macro.

That's how it was implemented originally on i386, but it didn't work. 

> Any idea?
>
(stuff omitted)
>
> > From: Manuel Novoa III [mailto:mnovoa3 at bellsouth.net]
>
> > However, vfork on i386 is definitely broken.  A test program 
> > to illustrate this
> > is attached.  The child executes but the parent segfaults.

What I did for i386 was grab the code from libc-5.3.12 (I think).  Just for ref,
here it is:

.text
        .align 4
.globl vfork
        .type    vfork, at function
vfork:
        popl %ecx
        movl $190,%eax
#APP
        int $0x80
#NO_APP
        cmpl $-4095,%eax
        jae .L5
        jmp *%ecx
        .p2align 4,,7
.L5:
        pushl %ecx
        negl %eax
        movl %eax,errno
        movl $-1,%eax
        ret
.Lfe1:
        .size    vfork,.Lfe1-vfork

Notice the "popl %ecx" right after entry.  The reason (I think) that the
syscall macro doesn't work in this case is that the vfork child and parent
share the same stack until the child does an execve or _exit.  When using the
syscall macro though, the child has already pop'd the return address off the
stack when the parent resumes execution.  So, when the parent tries to
return... bang!  The code above gets around that by poping the return address
into a register (which I'm assuming the kernel preserves for the parent) so
that the return address doesn't get lost.  At least, that's my interpretation.

Manuel








More information about the uClibc mailing list