From: "Lee Chin" <leechin@mail.com>
To: sos22@cam.ac.uk
Cc: linux-newbie@vger.kernel.org
Subject: Re: why does this program crash while using setcontext?
Date: Mon, 20 Jan 2003 11:12:46 -0500 [thread overview]
Message-ID: <20030120161246.51073.qmail@mail.com> (raw)
Thanks Steven... this works great... I now understand this api well thanks to you!
Best Wishes,
Lee
----- Original Message -----
From: Steven Smith <sos22@cam.ac.uk>
Date: Mon, 20 Jan 2003 14:32:40 +0000
To: Lee Chin <leechin@mail.com>
Subject: Re: why does this program crash while using setcontext?
> 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) Call foo() indirectly through one().
> 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 from foo() to main() 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 use makecontext() rather than getcontext().
>
> This means the design of the program looks more like this:
>
> 1) Have main() record its context. Call this the main context.
> 2) Have main() construct a context which will invoke foo() on a
> different stack. Call this the foo context.
> 3) Have main() 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.
>
> > ucontext_t mainucp;
> > ucontext_t fooucp;
> > int flag = 0;
> char stack[SIGSTKSZ];
>
> > int foo()
> > {
> > printf("(2) foo setting context\n");
>
> > getcontext(&fooucp);
> Kill this line - the foo context has already been constructed.
>
> > if (!flag)
> > {
> > flag = 1;
>
> > setcontext(&mainucp);
> Replace this line with:
> swapcontext(&fooucp, &mainucp);
> We need swapcontext() rather than setcontext() so as the foo
> context resumes from here, rather than the entry to one(),
> which would cause an infinite loop.
>
> > }
> > printf("(3) foo done\n");
> > return 0;
> > }
>
> <snip deeply nested call to foo() from one()>
>
> > 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_link line says to return the main context if the foo context
> ever returns. The uc_stack lines are just setting up the stack,
> and the makecontext() modified the foo context so that it calls
> one() with 0 arguments.
>
> For various reasons, primarily historical, contexts which are passed
> to makecontext() must first be initialised with getcontext(), even
> though makecontext() overwrites or makes redundant 95% of the work
> which getcontext() did.
>
> > getcontext(&mainucp);
> > if (!flag)
> > {
>
> > one();
> Replace this line with
> setcontext(&fooucp);
> Note that this is setcontext() and not swapcontext(); if we used
> swapcontext(), then the main context would resume from here
> rather than the call to getcontext(), above, and so the else
> branch of the if would never run.
>
> > }
> > else
> > {
> > printf("(2.5) main again\n");
>
> > setcontext(&fooucp);
> Replace this line with
> swapcontext(&mainucp, &fooucp);
> We need swapcontext() here, rather than setcontext(), because we
> want the main context to resume here rather than at the getcontext(),
> to avoid an infinite loop.
>
> > }
> Insert:
> return 0;
> :)
> > }
>
> Hopefully, that's a little clearer.
>
> In general, it's a good idea to use swapcontext() rather than
> setcontext() 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.
--
__________________________________________________________
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 majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.linux-learn.org/faqs
next reply other threads:[~2003-01-20 16:12 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-01-20 16:12 Lee Chin [this message]
-- strict thread matches above, loose matches on Subject: below --
2003-01-21 8:13 why does this program crash while using setcontext? Lee Chin
2003-01-21 16:39 ` Steven Smith
2003-01-20 6:10 Lee Chin
2003-01-20 14:32 ` Steven Smith
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20030120161246.51073.qmail@mail.com \
--to=leechin@mail.com \
--cc=linux-newbie@vger.kernel.org \
--cc=sos22@cam.ac.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.