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:
parent
40eb78eb74
commit
5c2f7646e1
3 changed files with 33 additions and 27 deletions
|
@ -47,36 +47,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
lwpNewContext(struct lwpProc *newp, int stacksz)
|
lwpNewContext(struct lwpProc *newp)
|
||||||
{
|
{
|
||||||
char *s;
|
if (getcontext(&newp->context) < 0)
|
||||||
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;
|
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
|
#ifdef MAKECONTEXT_SP_HIGH
|
||||||
/*
|
/*
|
||||||
* Known systems that are broken that way: Solaris prior to 10,
|
* Known systems that are broken that way: Solaris prior to 10,
|
||||||
* IRIX.
|
* IRIX.
|
||||||
*/
|
*/
|
||||||
newp->context.uc_stack.ss_sp = newp->ustack + stacksz - 8;
|
newp->context.uc_stack.ss_sp = newp->ustack + newp->usize - 8;
|
||||||
#else
|
#else
|
||||||
newp->context.uc_stack.ss_sp = newp->ustack;
|
newp->context.uc_stack.ss_sp = newp->ustack;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -127,6 +127,32 @@ lwpEntryPoint(void)
|
||||||
lwpExit();
|
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.
|
* lwpCreate -- create a process.
|
||||||
*/
|
*/
|
||||||
|
@ -147,19 +173,19 @@ lwpCreate(int priority, void (*entry)(void *), int stacksz,
|
||||||
newp->dead = 0;
|
newp->dead = 0;
|
||||||
newp->runtime = (time_t)-1;
|
newp->runtime = (time_t)-1;
|
||||||
newp->fd = -1;
|
newp->fd = -1;
|
||||||
|
newp->sbtm = NULL;
|
||||||
if (LWP_MAX_PRIO <= priority)
|
if (LWP_MAX_PRIO <= priority)
|
||||||
priority = LWP_MAX_PRIO - 1;
|
priority = LWP_MAX_PRIO - 1;
|
||||||
if (LwpMaxpri < (newp->pri = priority))
|
if (LwpMaxpri < (newp->pri = priority))
|
||||||
LwpMaxpri = priority;
|
LwpMaxpri = priority;
|
||||||
if (lwpNewContext(newp, stacksz) < 0) {
|
if (lwpNewStack(newp, stacksz) < 0 || lwpNewContext(newp) < 0) {
|
||||||
|
free(newp->sbtm);
|
||||||
free(newp->name);
|
free(newp->name);
|
||||||
free(newp);
|
free(newp);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
lwpStatus(newp, "creating process structure %p (sbtm %p)",
|
lwpStatus(newp, "creating process structure %p (sbtm %p)",
|
||||||
newp, newp->sbtm);
|
newp, newp->sbtm);
|
||||||
if (flags & LWP_STACKCHECK)
|
|
||||||
lwpStackCheckInit(newp);
|
|
||||||
lwpReady(newp);
|
lwpReady(newp);
|
||||||
lwpReady(LwpCurrent);
|
lwpReady(LwpCurrent);
|
||||||
lwpReschedule();
|
lwpReschedule();
|
||||||
|
|
|
@ -73,7 +73,7 @@ struct lwpQueue {
|
||||||
|
|
||||||
extern int LwpStackGrowsDown;
|
extern int LwpStackGrowsDown;
|
||||||
|
|
||||||
int lwpNewContext(struct lwpProc *, int);
|
int lwpNewContext(struct lwpProc *);
|
||||||
void lwpSwitchContext(struct lwpProc *, struct lwpProc *);
|
void lwpSwitchContext(struct lwpProc *, struct lwpProc *);
|
||||||
void lwpAddTail(struct lwpQueue *, struct lwpProc *);
|
void lwpAddTail(struct lwpQueue *, struct lwpProc *);
|
||||||
struct lwpProc *lwpGetFirst(struct lwpQueue *);
|
struct lwpProc *lwpGetFirst(struct lwpQueue *);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue