On Mon, Jun 27, 2005 at 03:04:19PM -0400, Greg Troxel wrote:
> I tried testlwp-static, and it too segfaults, after about 5 context
> switches.
> 
>   If the information is useful, it is probably better to use sigaction
>   with the SA_SIGINFO flag set, which is defined by POSIX.
> 
> I certainly agree that it's better to stick to standards.
> 
> uc_stack.ss_sp was nonnull, but pointed to 0.
> 
> Can anyone confirm if head lwp works on any version of NetBSD?

I kind of like the netbsd install, the initial setup is nice and very
lean. The only problem I have is that I definitely am far too used to
bash as a main shell, and less as the pager and such.

In any case, I found the problem. After the new context is first started
the ucontext.uc_stack variable seems to be clobbered. A simple fix is to
keep a separate copy saved so that we can check the stack overflow and
correctly free it whenever a thread exits.

I'm committing the following fix for it. I only tested it with a couple
of the lwp test programs (cswitch, testlwp, and rw).

Jan


Index: lwp.c
===================================================================
RCS file: /coda-src/lwp/src/lwp.c,v
retrieving revision 4.53
diff -u -r4.53 lwp.c
--- lwp.c       20 Jun 2005 19:31:10 -0000      4.53
+++ lwp.c       29 Jun 2005 18:35:36 -0000
@@ -519,7 +519,7 @@
 
 static void Dump_One_Process(PROCESS pid, FILE *fp)
 {
-    stack_t *stack = &pid->ctx.uc_stack;
+    stack_t *stack = &pid->stack;
     int i;
 
     fprintf(fp,"***LWP: process %s (%p)\n", pid->name, pid);
@@ -731,7 +731,7 @@
 
 static void Free_PCB(PROCESS pid)
 {
-    stack_t *stack = &pid->ctx.uc_stack;
+    stack_t *stack = &pid->stack;
 
     lwpdebug(0, "Entered Free_PCB");
 
@@ -787,8 +787,8 @@
        the guard word at the front of the stack being damaged.
        WARNING!  This code assumes that stacks grow downward. */
     if (lwp_cpptr && lwp_cpptr->stackcheck &&
-        (lwp_cpptr->stackcheck != *(int *)lwp_cpptr->ctx.uc_stack.ss_sp ||
-        (char *)&dummy < (char *)lwp_cpptr->ctx.uc_stack.ss_sp))
+        (lwp_cpptr->stackcheck != *(int *)lwp_cpptr->stack.ss_sp ||
+        (char *)&dummy < (char *)lwp_cpptr->stack.ss_sp))
     {
        switch (lwp_overflowAction) {
            case LWP_SOABORT:
@@ -875,8 +875,8 @@
        temp->stackcheck = *(int *)stack;
 
        getcontext(&temp->ctx);
-       temp->ctx.uc_stack.ss_sp = stack;
-       temp->ctx.uc_stack.ss_size = stacksize;
+       temp->stack.ss_sp = temp->ctx.uc_stack.ss_sp = stack;
+       temp->stack.ss_size = temp->ctx.uc_stack.ss_size = stacksize;
        temp->ctx.uc_link = &reaper; /* whenever a thread exits, we
                                        automatically reap it and schedule
                                        another runnable thread */
@@ -965,8 +965,8 @@
 
 int LWP_StackUsed(PROCESS pid, int *max, int *used)
 {
-    *max = pid->ctx.uc_stack.ss_size;
-    *used = Stack_Used(&pid->ctx.uc_stack);
+    *max = pid->stack.ss_size;
+    *used = Stack_Used(&pid->stack);
     if (*used == 0)
        return LWP_NO_STACK;
     return LWP_SUCCESS;
Index: lwp.private.h
===================================================================
RCS file: /coda-src/lwp/src/lwp.private.h,v
retrieving revision 4.16
diff -u -r4.16 lwp.private.h
--- lwp.private.h       3 Mar 2005 18:53:51 -0000       4.16
+++ lwp.private.h       29 Jun 2005 18:35:36 -0000
@@ -89,6 +89,7 @@
                                            incremented on each 
lwp_create_process */ 
   struct timeval lastReady;            /* if ready, time placed in the run 
queue */
 
+  stack_t    stack;                    /* allocated stack for this thread */
   ucontext_t ctx;                      /* saved context for next dispatch */
   };
 

Reply via email to