Linux Newbie help
 help / color / mirror / Atom feed
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

             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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox