fork() problems.

From: Tim Newsham <newsham_at_nospam.org>
Date: Wed Nov 30 1994 - 23:17:26 PST

I'm having problems again. I know, I know, its hard to believe.
"Tim is actually having problems?" Well its true :)

It seems I can fork()/wait()/exit() ok (most of the time) as done
by the "fork" command in the testsh. The second time I issue the
command, however, the system just dies. It dies so hard that the
hardclock() stops running (I have it print dots to the screen so
I know when something goes bad). The fork() command is behaving
properly the first time. I know this for sure because I am able
to fork off a child and exec a file (finally got that working after
switching to the VSTa ld). My guess is that something is going
bad in the exit routines. I did check the process table after the
fork()/exit() and the table seemed to still be in tact. In reviewing
things in machproc.c I've run across some questions:

in dup_stack():
        /*
         * New entity returns with 0 value; ESP is one lower so that
         * the resume() path has a place to write its return address.
         * This simulates the normal context switch mechanism of
         * setjmp/longjmp.
         */
        new->t_kregs->eip = (ulong)retuser;
        new->t_kregs->ebp = (ulong)(new->t_uregs);
        new->t_kregs->esp = (new->t_kregs->ebp) - sizeof(ulong);
        new->t_uregs->eax = 0;

I'm unclear on why the stack pointer is decremented by a word.

This buffer is later used by retuser() to warp to the new context
(restore registers from t_kregs). When the longjmp occurs the
instruction pointer gets set to "retuser" which causes the program
to enter the retuser() function (again). How does a process
continue execution if it keeps warping back to retuser()?

What is the function of ebp? I don't believe the 68k has an
analagous register (a dedicated one at least). The 68k uses
the link command at the entry of a function which acts similarly
to ebp (correct?). If the longjmp warps to a function that
does this then the link register doesnt have to be set does it?

At any rate here is the code I am working with right now:

        /*
         * New entity returns with 0 value; SP is one lower so that
         * the resume() path has a place to write its return address.
         * This simulates the normal context switch mechanism of
         * setjmp/longjmp.
         */
        new->t_kregs->pc = (ulong)retuser;
        new->t_kregs->sp = ((ulong)(new->t_uregs)) - sizeof(ulong);
        new->t_uregs->f_regs[REG_D0] = 0;

you'll notice this is basically just a blind copy of the above.

in resume():
        /*
         * Make kernel stack come in on our own stack now. This
         * isn't used until we switch out to user mode, at which
         * time our stack will always be empty.
         * XXX esp is overkill; only esp0 should ever be used.
         */
        tss->esp0 = tss->esp = (ulong)
                ((char *)(t->t_kstack) + KSTACK_SIZE);

This one has me really confused. I'm not to clear on what the tss
does. In my port I have this stuff commented out. I have a feeling
this has something to do with my problems and the 1 word space left
on the stack after the longjmp.

What amazes me is that even for my limited understanding of this
that my port is actually working. Tasks are switching in and out
fine and I have one process which does a tfork() successfully and
I can do one fork()/exec() pair fine (although not two in a row).

My brain is hurting right now, I hope that most of this post has
some coherence.

                              Tim N.
Received on Wed Nov 30 22:54:05 1994

This archive was generated by hypermail 2.1.8 : Thu Sep 22 2005 - 15:12:10 PDT