why does this program crash while using setcontext?
Thanks Steven... this works great... I now understand this api well thanks to you!
Best Wishes,
Lee
----- Original Message -----
From: Steven Smith <[email protected]>
Date: Mon, 20 Jan 2003 14:32:40 +0000
To: Lee Chin <[email protected]>
Subject: Re: why does this program crash while using setcontext?
Quoted 126 lines
I think this problem is largely my fault; I should have been more clear last time I posted. Feel free to insult me.
I think the program below is trying to:
1) have
main()record its context immediately. Call this the main context.
2) Callfoo()indirectly throughone().
3) Record foo()'s context. Call this the foo context.
4) Switch back to the main context.
5) Switch back to the foo context.
6) Return back fromfoo()tomain()and then exit.Now, the problem is that the various contexts are all running on the same stack. This means that the bit of
main()which runs between steps 4 and 5 is mangling the foo context, and so step 6 doesn't work.The way to avoid this is to have the two contexts operating on different stacks. The main context can happily run on the process stack, but one will need to be allocated for the foo context. An array of chars is perfectly good for this; the usual size is SIGSTKSZ, defined in
signal.h. In addition, we need to tell the ucontext functions to use this stack. Unfortunately, there's no (easy) way to copy the current stack onto the context stack, and so we need to usemakecontext()rather thangetcontext().This means the design of the program looks more like this:
1) Have
main()record its context. Call this the main context.
2) Havemain()construct a context which will invokefoo()on a different stack. Call this the foo context.
3) Havemain()invoke the foo context.
4) Switch back to the main context.
5) Switch back to the foo context.
6) Let the foo context return. This will cause the context library to automatically switch back to the main context, which can then return and exit the program.I've shown these changes below.
Quoted 3 lines
ucontext_tmainucp;ucontext_tfooucp;
int flag = 0;char stack[SIGSTKSZ];
Quoted 5 lines
int
foo(){ printf("(2) foo setting context\n"); getcontext(&fooucp);Kill this line - the foo context has already been constructed.
Quoted 5 lines
if (!flag) { flag = 1; setcontext(&mainucp);Replace this line with:
swapcontext(&fooucp, &mainucp);We need
swapcontext()rather thansetcontext()so as the foo context resumes from here, rather than the entry toone(), which would cause an infinite loop.Quoted 4 lines
} printf("(3) foo done\n"); return 0; }<snip deeply nested call to
foo()fromone()>Quoted 2 lines
int
main()
{Insert
getcontext(&fooucp); fooucp.uc_link = &mainucp; fooucp.uc_stack.ss_sp = stack; fooucp.uc_stack.ss_size = sizeof(stack); makecontext(&fooucp, one, 0);The
uc_linkline says to return the main context if the foo context ever returns. Theuc_stacklines are just setting up the stack, and themakecontext()modified the foo context so that it callsone()with 0 arguments.For various reasons, primarily historical, contexts which are passed to
makecontext()must first be initialised withgetcontext(), even thoughmakecontext()overwrites or makes redundant 95% of the work whichgetcontext()did.Quoted 5 lines
getcontext(&mainucp); if (!flag) { one();Replace this line with
setcontext(&fooucp);Note that this is
setcontext()and notswapcontext(); if we usedswapcontext(), then the main context would resume from here rather than the call togetcontext(), above, and so the else branch of the if would never run.Quoted 6 lines
} else { printf("(2.5) main again\n"); setcontext(&fooucp);Replace this line with
swapcontext(&mainucp, &fooucp);We need
swapcontext()here, rather thansetcontext(), because we want the main context to resume here rather than at thegetcontext(), to avoid an infinite loop.Quoted 1 line
}Insert:
return 0;:)
Quoted 1 line
}
Hopefully, that's a little clearer.
In general, it's a good idea to use
swapcontext()rather thansetcontext()if at all possible, because then functions return to the same place as they were called from, which is a lot easier to think about.Steven.
Signature · 12 lines
__________________________________________________________ Sign-up for your own FREE Personalized E-mail at Mail.com http://www.mail.com/?sr=signup Meet Singles http://corp.mail.com/lavalife - To unsubscribe from this list: send the line "unsubscribe linux-newbie" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.linux-learn.org/faqs