[context] Linux x64 / printf

I modified the 'jump.cpp' example and added the line marked CRASH in f1() #include <cstdlib> #include <cstring> #include <iostream> #include <vector> #include <boost/assert.hpp> #include <boost/context/all.hpp> namespace ctx = boost::ctx; ctx::fcontext_t fcm, fc1, fc2; void f1( intptr_t) { std::cout<<"hello "<<0; // WORKS printf( "hello %d", 0 ); // <<< CRASH std::cout << "f1: entered" << std::endl; std::cout << "f1: call jump_fcontext( & fc1, & fc2, 0)" << std::endl; ctx::jump_fcontext( & fc1, & fc2, 0); std::cout << "f1: return" << std::endl; ctx::jump_fcontext( & fc1, & fcm, 0); } void f2( intptr_t) { std::cout << "f2: entered" << std::endl; std::cout << "f2: call jump_fcontext( & fc2, & fc1, 0)" << std::endl; ctx::jump_fcontext( & fc2, & fc1, 0); BOOST_ASSERT( false && ! "f2: never returns"); } int main( int argc, char * argv[]) { ctx::stack_allocator alloc1, alloc2; fc1.fc_stack.base = alloc1.allocate(ctx::minimum_stacksize()); fc1.fc_stack.limit = static_cast< char * >( fc1.fc_stack.base) - ctx::minimum_stacksize(); ctx::make_fcontext( & fc1, f1); fc2.fc_stack.base = alloc2.allocate(ctx::minimum_stacksize()); fc2.fc_stack.limit = static_cast< char * >( fc2.fc_stack.base) - ctx::minimum_stacksize(); ctx::make_fcontext( & fc2, f2); std::cout << "main: call start_fcontext( & fcm, & fc1, 0)" << std::endl; ctx::jump_fcontext( & fcm, & fc1, 0); std::cout << "main: done" << std::endl; return EXIT_SUCCESS; }

On 11.9.2012 5:00, Daniel Larimer wrote:
I modified the 'jump.cpp' example and added the line marked CRASH in f1()
#include <cstdlib> #include <cstring> #include <iostream> #include <vector>
...
void f1( intptr_t) { std::cout<<"hello "<<0; // WORKS printf( "hello %d", 0 ); // <<< CRASH std::cout << "f1: entered" << std::endl; std::cout << "f1: call jump_fcontext( & fc1, & fc2, 0)" << std::endl; ctx::jump_fcontext( & fc1, & fc2, 0); std::cout << "f1: return" << std::endl; ctx::jump_fcontext( & fc1, & fcm, 0); }
I guess printf should be pulled from cstdio (not that you should use it, printf that is, in the first place), so perhaps your compiler is using some short of build-in instead which causes the crash. -- Pekka

On Tue, Sep 11, 2012 at 1:57 AM, Pekka Seppänen < pekka.seppanen@capricode.com> wrote:
On 11.9.2012 5:00, Daniel Larimer wrote:
I modified the 'jump.cpp' example and added the line marked CRASH in f1()
#include <cstdlib> #include <cstring> #include <iostream> #include <vector>
...
void f1( intptr_t) { std::cout<<"hello "<<0; // WORKS printf( "hello %d", 0 ); // <<< CRASH std::cout << "f1: entered" << std::endl; std::cout << "f1: call jump_fcontext( & fc1, & fc2, 0)" <<
std::endl;
ctx::jump_fcontext( & fc1, & fc2, 0); std::cout << "f1: return" << std::endl; ctx::jump_fcontext( & fc1, & fcm, 0); }
I guess printf should be pulled from cstdio (not that you should use it, printf that is, in the first place), so perhaps your compiler is using some short of build-in instead which causes the crash.
I am just using the standard compiler... the reason I was using printf() is because I wanted to avoid including all of iostream in every build... accelerate compile times. Fortunately, I wrap all of my console prints in a debug macro that made it easy for me to switch to iostream at the expense of doubling my compile times. If it were simply a 'stack size' issue then it still wouldn't solve my problem because I really to do want the minimum stack size as I have a lot of async operations where the state is managed on the 'stack'.
-- Pekka
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Am 11.09.2012 18:14, schrieb Daniel Larimer:
On Tue, Sep 11, 2012 at 1:57 AM, Pekka Seppänen < pekka.seppanen@capricode.com> wrote:
On 11.9.2012 5:00, Daniel Larimer wrote:
I modified the 'jump.cpp' example and added the line marked CRASH in f1()
#include <cstdlib> #include <cstring> #include <iostream> #include <vector>
...
void f1( intptr_t) { std::cout<<"hello "<<0; // WORKS printf( "hello %d", 0 ); // <<< CRASH std::cout << "f1: entered" << std::endl; std::cout << "f1: call jump_fcontext( & fc1, & fc2, 0)" << std::endl; ctx::jump_fcontext( & fc1, & fc2, 0); std::cout << "f1: return" << std::endl; ctx::jump_fcontext( & fc1, & fcm, 0); } I guess printf should be pulled from cstdio (not that you should use it, printf that is, in the first place), so perhaps your compiler is using some short of build-in instead which causes the crash.
I am just using the standard compiler... the reason I was using printf() is because I wanted to avoid including all of iostream in every build... accelerate compile times.
Fortunately, I wrap all of my console prints in a debug macro that made it easy for me to switch to iostream at the expense of doubling my compile times.
If it were simply a 'stack size' issue then it still wouldn't solve my problem because I really to do want the minimum stack size as I have a lot of async operations where the state is managed on the 'stack'.
your app does not crash (cstdio must be included) on my x86_64 Linux system

On Sep 11, 2012, at 12:56 PM, Oliver Kowalke <oliver.kowalke@gmx.de> wrote:
Am 11.09.2012 18:14, schrieb Daniel Larimer:
On Tue, Sep 11, 2012 at 1:57 AM, Pekka Seppänen < pekka.seppanen@capricode.com> wrote:
On 11.9.2012 5:00, Daniel Larimer wrote:
I modified the 'jump.cpp' example and added the line marked CRASH in f1()
#include <cstdlib> #include <cstring> #include <iostream> #include <vector>
...
void f1( intptr_t) { std::cout<<"hello "<<0; // WORKS printf( "hello %d", 0 ); // <<< CRASH std::cout << "f1: entered" << std::endl; std::cout << "f1: call jump_fcontext( & fc1, & fc2, 0)" << std::endl; ctx::jump_fcontext( & fc1, & fc2, 0); std::cout << "f1: return" << std::endl; ctx::jump_fcontext( & fc1, & fcm, 0); } I guess printf should be pulled from cstdio (not that you should use it, printf that is, in the first place), so perhaps your compiler is using some short of build-in instead which causes the crash.
I am just using the standard compiler... the reason I was using printf() is because I wanted to avoid including all of iostream in every build... accelerate compile times.
Fortunately, I wrap all of my console prints in a debug macro that made it easy for me to switch to iostream at the expense of doubling my compile times.
If it were simply a 'stack size' issue then it still wouldn't solve my problem because I really to do want the minimum stack size as I have a lot of async operations where the state is managed on the 'stack'.
your app does not crash (cstdio must be included) on my x86_64 Linux system
You are right, printf() does not crash, but fprintf( stderr, "hello %d", 0 ) does seem to crash... I simplified it too much for the bug report. To be fair, fprintf( stdout, "hello %d", 0 ) also works... so it appears to only be stderr that is crashing. Using fprintf( stderr, "..." ) in main works just fine, it is only from the context of f1() that there is a problem.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On Sep 11, 2012, at 8:27 PM, Daniel Larimer <dlarimer@gmail.com> wrote:
On Sep 11, 2012, at 12:56 PM, Oliver Kowalke <oliver.kowalke@gmx.de> wrote:
Am 11.09.2012 18:14, schrieb Daniel Larimer:
On Tue, Sep 11, 2012 at 1:57 AM, Pekka Seppänen < pekka.seppanen@capricode.com> wrote:
On 11.9.2012 5:00, Daniel Larimer wrote:
I modified the 'jump.cpp' example and added the line marked CRASH in f1()
#include <cstdlib> #include <cstring> #include <iostream> #include <vector>
...
void f1( intptr_t) { std::cout<<"hello "<<0; // WORKS printf( "hello %d", 0 ); // <<< CRASH std::cout << "f1: entered" << std::endl; std::cout << "f1: call jump_fcontext( & fc1, & fc2, 0)" << std::endl; ctx::jump_fcontext( & fc1, & fc2, 0); std::cout << "f1: return" << std::endl; ctx::jump_fcontext( & fc1, & fcm, 0); } I guess printf should be pulled from cstdio (not that you should use it, printf that is, in the first place), so perhaps your compiler is using some short of build-in instead which causes the crash.
I am just using the standard compiler... the reason I was using printf() is because I wanted to avoid including all of iostream in every build... accelerate compile times.
Fortunately, I wrap all of my console prints in a debug macro that made it easy for me to switch to iostream at the expense of doubling my compile times.
If it were simply a 'stack size' issue then it still wouldn't solve my problem because I really to do want the minimum stack size as I have a lot of async operations where the state is managed on the 'stack'.
your app does not crash (cstdio must be included) on my x86_64 Linux system
You are right, printf() does not crash, but fprintf( stderr, "hello %d", 0 ) does seem to crash... I simplified it too much for the bug report. To be fair, fprintf( stdout, "hello %d", 0 ) also works... so it appears to only be stderr that is crashing.
Using fprintf( stderr, "..." ) in main works just fine, it is only from the context of f1() that there is a problem.
I can confirm that using default_stacksize() instead of minimum stack size fixes the problem. So it would appear that stderr must use the stack for scratch space. So apparently, linux has a min stack size of 8kb which is relatively small!
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

I can confirm that using default_stacksize() instead of minimum stack size fixes the problem.
fine ;)
So it would appear that stderr must use the stack for scratch space. So apparently, linux has a min stack size of 8kb which is relatively small!
It's a general problem that boost.context can not predict how much stack space would be required. With automatically growing stack (like GCC's split stacks) the problewm would be gone - unfortunately no standard for such a stack API exists. Oliver

On 09/11/2012 08:17 AM, Oliver Kowalke wrote:
fc1.fc_stack.base = alloc1.allocate(ctx::minimum_stacksize());
maybe your stacksize is too small - use for instance default_stacksize()
Somewhat off-topic, but does Boost.Context support specifying automatic stack growth as supported by Linux?

fc1.fc_stack.base = alloc1.allocate(ctx::minimum_stacksize());
maybe your stacksize is too small - use for instance default_stacksize()
Somewhat off-topic, but does Boost.Context support specifying automatic stack growth as supported by Linux?
yes, it is planed. gcc supports split-stacks. unfortunately this feature requires the gold linker.. Oliver
participants (4)
-
Daniel Larimer
-
Mathias Gaunard
-
Oliver Kowalke
-
Pekka Seppänen