Fix LWP's stack initialization for -s

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().
This commit is contained in:
Markus Armbruster 2008-02-14 23:47:27 +01:00
parent 40eb78eb74
commit 5c2f7646e1
3 changed files with 33 additions and 27 deletions

View file

@ -47,36 +47,16 @@
*/
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)
if (getcontext(&newp->context) < 0)
return -1;
newp->sbtm = s;
newp->size = size;
newp->ustack = s + redsize;
newp->usize = stacksz;
if (getcontext(&newp->context) < 0) {
free(s);
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

View 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();

View 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 *);