]> git.pond.sub.org Git - empserver/commitdiff
Fix LWP's stack initialization for -s
authorMarkus Armbruster <armbru@pond.sub.org>
Thu, 14 Feb 2008 22:47:27 +0000 (23:47 +0100)
committerMarkus Armbruster <armbru@pond.sub.org>
Sat, 16 Feb 2008 19:57:38 +0000 (20:57 +0100)
With -s, LWP initializes thread stacks to track stack use.  It did
that after makecontext(), with disastrous results on systems where
makecontext() writes something to the stack that swapcontext() expects
to find there.  Makes FreeBSD 6.2 crash in swapcontext().

Factor stack allocation out of lwpNewContext() into lwpNewStack().
Move call of lwpStackCheckInit() into lwpNewStack().

src/lib/lwp/arch.c
src/lib/lwp/lwp.c
src/lib/lwp/lwpint.h

index 7022eb29f4597b52a56b6d5fd573f4d3225c6bd9..f4107b43a57004b4aa7f096771764c2ff1b1707e 100644 (file)
  */
 
 int
-lwpNewContext(struct lwpProc *newp, int stacksz)
+lwpNewContext(struct lwpProc *newp)
 {
-    char *s;
-    int size, redsize;
-
-    /* Make size a multiple of sizeof(long) to keep things aligned */
-    stacksz = (stacksz + sizeof(long) - 1) & -sizeof(long);
-    /* Add a red zone on each side of the stack for LWP_STACKCHECK */
-    redsize = newp->flags & LWP_STACKCHECK ? LWP_REDZONE : 0;
-    size = stacksz + 2 * redsize;
-
-    s = malloc(size);
-    if (!s)
-       return -1;
-
-    newp->sbtm = s;
-    newp->size = size;
-    newp->ustack = s + redsize;
-    newp->usize = stacksz;
-
-    if (getcontext(&newp->context) < 0) {
-       free(s);
+    if (getcontext(&newp->context) < 0)
        return -1;
-    }
 #ifdef MAKECONTEXT_SP_HIGH
     /*
      * Known systems that are broken that way: Solaris prior to 10,
      * IRIX.
      */
-    newp->context.uc_stack.ss_sp = newp->ustack + stacksz - 8;
+    newp->context.uc_stack.ss_sp = newp->ustack + newp->usize - 8;
 #else
     newp->context.uc_stack.ss_sp = newp->ustack;
 #endif
index 01c3384c59d449c9232b2eaa9128fd87d151c515..85a2636d410111240490c553e45b0d34e118bd64 100644 (file)
@@ -127,6 +127,32 @@ lwpEntryPoint(void)
     lwpExit();
 }
 
+static int
+lwpNewStack(struct lwpProc *newp, int stacksz)
+{
+    char *s;
+    int size, redsize;
+
+    /* Make size a multiple of sizeof(long) to keep things aligned */
+    stacksz = (stacksz + sizeof(long) - 1) & -sizeof(long);
+    /* Add a red zone on each side of the stack for LWP_STACKCHECK */
+    redsize = newp->flags & LWP_STACKCHECK ? LWP_REDZONE : 0;
+    size = stacksz + 2 * redsize;
+
+    s = malloc(size);
+    if (!s)
+       return -1;
+
+    newp->sbtm = s;
+    newp->size = size;
+    newp->ustack = s + redsize;
+    newp->usize = stacksz;
+
+    if (newp->flags & LWP_STACKCHECK)
+       lwpStackCheckInit(newp);
+    return 0;
+}
+
 /*
  * lwpCreate -- create a process.
  */
@@ -147,19 +173,19 @@ lwpCreate(int priority, void (*entry)(void *), int stacksz,
     newp->dead = 0;
     newp->runtime = (time_t)-1;
     newp->fd = -1;
+    newp->sbtm = NULL;
     if (LWP_MAX_PRIO <= priority)
        priority = LWP_MAX_PRIO - 1;
     if (LwpMaxpri < (newp->pri = priority))
        LwpMaxpri = priority;
-    if (lwpNewContext(newp, stacksz) < 0) {
+    if (lwpNewStack(newp, stacksz) < 0 || lwpNewContext(newp) < 0) {
+       free(newp->sbtm);
        free(newp->name);
        free(newp);
        return NULL;
     }
     lwpStatus(newp, "creating process structure %p (sbtm %p)",
              newp, newp->sbtm);
-    if (flags & LWP_STACKCHECK)
-       lwpStackCheckInit(newp);
     lwpReady(newp);
     lwpReady(LwpCurrent);
     lwpReschedule();
index c887f5e6f471c3ce6d696beacb7691a8a2e77ba2..23dde3142a92fc543f7f82e25d5238d6ca22f240 100644 (file)
@@ -73,7 +73,7 @@ struct lwpQueue {
 
 extern int LwpStackGrowsDown;
 
-int lwpNewContext(struct lwpProc *, int);
+int lwpNewContext(struct lwpProc *);
 void lwpSwitchContext(struct lwpProc *, struct lwpProc *);
 void lwpAddTail(struct lwpQueue *, struct lwpProc *);
 struct lwpProc *lwpGetFirst(struct lwpQueue *);