From: Steven Smith <sos22@cam.ac.uk>
To: Lee Chin <leechin@mail.com>
Cc: linux-newbie@vger.kernel.org
Subject: Re: why does this program crash while using setcontext?
Date: Tue, 21 Jan 2003 16:39:34 +0000 [thread overview]
Message-ID: <20030121163934.GA4303@cam.ac.uk> (raw)
In-Reply-To: <20030121081327.69768.qmail@mail.com>
[-- Attachment #1: Type: text/plain, Size: 2417 bytes --]
One day, I'll learn to think before posting, and possibly check
that whatever I'm suggesting actually works...
> One thing I dont understand is why if I use setcontext instead of
> swapcontext in the following program, I crash? Look at where I
> commented out my swapcontext
The problem here is that the foo context is being invoked twice
with the same set of registers, but a different stack setup.
The first time foo is invoked, it runs through one(), setting up a
return stack in the stack buffer, before invoking the main context.
The main context then re-invokes the foo context, which returns back
through its call stack, destroying it in the process. main then
invokes foo again, resulting in weird stack corruption problems
and a crash. One possible fix is shown below.
> #include <ucontext.h>
> #include <stdio.h>
> #include <setjmp.h>
>
> ucontext_t mainucp;
> ucontext_t fooucp;
>
> char stack[SIGSTKSZ];
Add another stack buffer:
char ostack[SIGSTKSZ];
<snip unchanged code>
> int main()
> {
Add
volatile int count;
count = 0;
This counts the number of times the main context has resumed.
> getcontext(&fooucp);
> fooucp.uc_link = &mainucp;
Note that when the foo context returns, the main context is invoked
immediately i.e. without trying to save foo's registers
(which wouldn't actually make much sense). This means that
the foo context now contains registers suitable for running
foo(), but a stack suitable for running the end of one(). This
is a bad thing.
> fooucp.uc_stack.ss_sp = stack;
> fooucp.uc_stack.ss_size = sizeof(stack);
> makecontext(&fooucp, one, 0);
> getcontext(&mainucp);
Add
if (count == 1) {
memcpy(ostack, stack, sizeof(stack));
} else if (count > 1) {
memcpy(stack, ostack, sizeof(stack));
}
count++;
This saves a copy of the foo context's stack the first time it switches
to main, and then restores it on later occasions. This is ugly,
but it's probably the only way you're going to be able to re-use
contexts which have returned.
> printf("(1, 2.2) main checking flag flag\n");
> if (!flag)
> {
> setcontext(&fooucp);
> }
> else
> {
> printf("(2.5) main again\n");
> setcontext(&fooucp);
> }
> }
I should probably apologise for not going into nearly enough detail
for such an obscure API.
Steven.
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
next prev parent reply other threads:[~2003-01-21 16:39 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-01-21 8:13 why does this program crash while using setcontext? Lee Chin
2003-01-21 16:39 ` Steven Smith [this message]
-- strict thread matches above, loose matches on Subject: below --
2003-01-20 16:12 Lee Chin
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=20030121163934.GA4303@cam.ac.uk \
--to=sos22@cam.ac.uk \
--cc=leechin@mail.com \
--cc=linux-newbie@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox