Discussion:
[Boost-users] Boost.Context stack growing inwards
Thomas Ziegenhagen
2016-02-29 14:10:21 UTC
Permalink
Hi there,

I get regular crashes when using Boost.Context after just a few calls to
make_fcontext(). I built a minimal example as follows:

----
#include <iostream>
#include <vector>
#include <boost/context/all.hpp>

struct Context
{
boost::context::fcontext_t c_outside, c_inside;
};
Context gContext = { nullptr, nullptr };

void DoIt( intptr_t /*pt*/)
{
uint8_t test[64];
memset( test, 0xaf, sizeof( test));

std::cout << "DoIt(), Point 1" << std::endl;
boost::context::jump_fcontext( &gContext.c_inside, gContext.c_outside,
0, true);
std::cout << "DoIt(), Point 2" << std::endl;
boost::context::jump_fcontext( &gContext.c_inside, gContext.c_outside,
0, true);
std::cout << "DoIt(), Point 3" << std::endl;
boost::context::jump_fcontext( &gContext.c_inside, gContext.c_outside,
0, true);
}

int main()
{
const size_t StackSize = 16384;
std::vector<uint8_t> stack( StackSize, 0xf1);
gContext.c_inside = boost::context::make_fcontext( stack.data() + 256,
stack.size() - 512, DoIt);

std::cout << "main(), Point 1" << std::endl;
boost::context::jump_fcontext( &gContext.c_outside, gContext.c_inside,
0, true);
std::cout << "main(), Point 2" << std::endl;
boost::context::jump_fcontext( &gContext.c_outside, gContext.c_inside,
0, true);
std::cout << "main(), Point 3" << std::endl;
boost::context::jump_fcontext( &gContext.c_outside, gContext.c_inside,
0, true);
std::cout << "main(), Point 4" << std::endl;

return 0;
}
------

This notable thing is that I provide a stack with additional 256 bytes of
safety borders. And it turns out: the provided memory is overwritten way
beyond the beginning. The actual designated area is not touched at all,
but instead the area before the beginning is overwritten. The only thing I
found in the documentation is this:

"sp Member: Pointer to the beginning of the stack (depending of the
architecture the stack grows downwards or upwards)."

which hints that on some system the stack might grow to negative
addresses. But up to now I thought that boost.context knows which
direction is correct, and adjusts the given pointer accordingly. But
apparently it doesn't. Or the environment underwent a drastic change. Here
it is Windows 10 64bit, Visual Studio 2015.

For readers remembering my last mails: I have verified this also with an
"classic" boost build using this command line:

b2.exe -a --reconfigure variant=debug,release link=static
runtime-link=static --with-context

So I'm pretty sure it's not a build issue.

Question: is this a bug? Probably not, I'm surely not the first to use
Boost.Context, so I wonder what the correct way is to handle this issue.
So what do I do about this?

Thanks in advance

Bye, Thomas
Thomas Ziegenhagen
2016-02-29 14:19:38 UTC
Permalink
Hi again,

just noticed that the make_fcontext() documentation says that it expects
the stack pointer to be at the end or at the beginning, depending on the
architecture.

So please re-read my last mail as a feature request:

If Boost.Context is a platform-independent context switching library,
please make its stack pointer parameter also platform-independent.

Rationale:

Booost.Context knows best on which platform it runs. If the API is
supposed to work the same on all supported systems, its parameter should
do so, too.

Other than that: Sorry for wasting your time.

Bye, Thomas
TONGARI J
2016-02-29 15:12:32 UTC
Permalink
Post by Thomas Ziegenhagen
Hi again,
just noticed that the make_fcontext() documentation says that it expects
the stack pointer to be at the end or at the beginning, depending on the
architecture.
If Boost.Context is a platform-independent context switching library,
please make its stack pointer parameter also platform-independent.
Booost.Context knows best on which platform it runs. If the API is
supposed to work the same on all supported systems, its parameter should do
so, too.
Other than that: Sorry for wasting your time.
I have the same opinion and I had argued that with the lib author, but he
somewhat insisted that Booost.Context should not do so... :(

See:
http://boost.2283326.n4.nabble.com/context-How-to-set-stack-pointer-in-a-platform-independent-way-td4667731.html
Oliver Kowalke
2016-02-29 15:27:36 UTC
Permalink
Post by TONGARI J
Post by Thomas Ziegenhagen
Hi again,
just noticed that the make_fcontext() documentation says that it expects
the stack pointer to be at the end or at the beginning, depending on the
architecture.
If Boost.Context is a platform-independent context switching library,
please make its stack pointer parameter also platform-independent.
Booost.Context knows best on which platform it runs. If the API is
supposed to work the same on all supported systems, its parameter should do
so, too.
Other than that: Sorry for wasting your time.
I have the same opinion and I had argued that with the lib author, but he
somewhat insisted that Booost.Context should not do so... :(
because fcontext-API is no longer part of the public API

Loading...