Nat Goodspeed wrote:
the 'banana' example program built -- but I get a bus
error trying to run it.
I did find an exchange on the Apple mailing list [1] in which Kevin Van
Vechten recommends #defining _XOPEN_SOURCE before #include .
Unfortunately, adding such a #define does not resolve my bus error.
banana.cpp now runs on my Mac! For closure, here's what I found.
There were two crash issues. One is indeed fixed by #defining
_XOPEN_SOURCE -- /if/ your #define precedes the first #include of
sys/_structs.h! This was a little tricky to resolve, since many system
headers end up pulling that in.
This only matters in boost/coroutine/detail/context_posix.hpp, so I kept
the #define there -- but test whether the system file has already been
#included. If so, you get an #error to the effect that you must #include
coroutine headers before anything that #includes .
Then I had to move some internal #includes that were forcing that #error
even when coroutine.hpp is first.
Moving boost/coroutine/detail/context_posix.hpp before most other
#includes revealed that it uses BOOST_ASSERT without #including
. I've added that #include.
The other crash issue is that 8192 is way too small a default stack. On
this platform, SIGSTKSZ is 131072, or 16x the hard-coded
default_stack_size. I changed the definition of
ucontext_context_impl::default_stack_size to SIGSTKSZ.
I changed boost/coroutine/detail/posix_utility.hpp to reference MAP_ANON
rather than MAP_ANONYMOUS in the __APPLE__ case -- thanks Tom!
All these changes are in a patch file [2].
[1] http://lists.apple.com/archives/darwin-dev/2008/Jan/msg00232.html
[2] attached boost-coroutine.patch
diff -cr orig/boost-coroutine/boost/coroutine/coroutine.hpp ./boost/coroutine/coroutine.hpp
*** orig/boost-coroutine/boost/coroutine/coroutine.hpp Sun Aug 20 13:11:16 2006
--- ./boost/coroutine/coroutine.hpp Tue Apr 7 23:38:11 2009
***************
*** 28,33 ****
--- 28,35 ----
#ifndef BOOST_COROUTINE_COROUTINE_HPP_20060512
#define BOOST_COROUTINE_COROUTINE_HPP_20060512
+ // default_context_impl.hpp must be first for weird Apple bug
+ #include
#include <cstddef>
#include
#include
***************
*** 37,43 ****
#include
#include
#include
- #include
#include
#include
#include
--- 39,44 ----
diff -cr orig/boost-coroutine/boost/coroutine/detail/context_posix.hpp ./boost/coroutine/detail/context_posix.hpp
*** orig/boost-coroutine/boost/coroutine/detail/context_posix.hpp Sun Aug 20 13:11:09 2006
--- ./boost/coroutine/detail/context_posix.hpp Tue Apr 7 23:40:17 2009
***************
*** 28,39 ****
#ifndef BOOST_COROUTINE_CONTEXT_POSIX_HPP_20060601
#define BOOST_COROUTINE_CONTEXT_POSIX_HPP_20060601
#include
#if defined(_XOPEN_UNIX) && defined(_XOPEN_VERSION) && _XOPEN_VERSION >= 500
/*
! * makecontex based context implementation. Should be available on all
* SuSv2 compliant UNIX systems.
* NOTE: this implementation is not
* optimal as the makecontext API saves and restore the signal mask.
--- 28,55 ----
#ifndef BOOST_COROUTINE_CONTEXT_POSIX_HPP_20060601
#define BOOST_COROUTINE_CONTEXT_POSIX_HPP_20060601
+
+ // NOTE (per http://lists.apple.com/archives/darwin-dev/2008/Jan/msg00232.html):
+ // > Why the bus error? What am I doing wrong?
+ // This is a known issue where getcontext(3) is writing past the end of the
+ // ucontext_t struct when _XOPEN_SOURCE is not defined (rdar://problem/5578699 ).
+ // As a workaround, define _XOPEN_SOURCE before including ucontext.h.
+ #if defined(__APPLE__) && ! defined(_XOPEN_SOURCE)
+ #define _XOPEN_SOURCE
+ // However, the above #define will only affect if it has not yet
+ // been #included by something else!
+ #if defined(_STRUCT_UCONTEXT)
+ #error You must #include coroutine headers before anything that #includes
+ #endif
+ #endif
+
#include
+ #include
#if defined(_XOPEN_UNIX) && defined(_XOPEN_VERSION) && _XOPEN_VERSION >= 500
/*
! * makecontext based context implementation. Should be available on all
* SuSv2 compliant UNIX systems.
* NOTE: this implementation is not
* optimal as the makecontext API saves and restore the signal mask.
***************
*** 43,48 ****
--- 59,65 ----
* it is unlikely that they will be removed any time soon.
*/
#include
+ #include // SIGSTKSZ
#include
#include
#include
***************
*** 83,89 ****
public:
typedef ucontext_context_impl_base context_impl_base;
! enum {default_stack_size = 8192};
/**
--- 100,106 ----
public:
typedef ucontext_context_impl_base context_impl_base;
! enum {default_stack_size = SIGSTKSZ};
/**
diff -cr orig/boost-coroutine/boost/coroutine/detail/posix_utility.hpp ./boost/coroutine/detail/posix_utility.hpp
*** orig/boost-coroutine/boost/coroutine/detail/posix_utility.hpp Sun Aug 20 13:11:09 2006
--- ./boost/coroutine/detail/posix_utility.hpp Wed Apr 1 09:57:03 2009
***************
*** 129,135 ****
--- 129,139 ----
void * stack = ::mmap(NULL,
size,
PROT_EXEC|PROT_READ|PROT_WRITE,
+ #if defined(__APPLE__)
+ MAP_PRIVATE|MAP_ANON,
+ #else // ! __APPLE__
MAP_PRIVATE|MAP_ANONYMOUS,
+ #endif // ! __APPLE__
-1,
0
);
diff -cr orig/boost-coroutine/boost/coroutine/future.hpp ./boost/coroutine/future.hpp
*** orig/boost-coroutine/boost/coroutine/future.hpp Sun Aug 20 13:11:16 2006
--- ./boost/coroutine/future.hpp Tue Apr 7 23:38:42 2009
***************
*** 33,38 ****
--- 33,40 ----
#ifndef BOOST_COROUTINE_WAIT_MAX
#define BOOST_COROUTINE_WAIT_MAX 10
#endif
+ // default_context_impl.hpp must be first for weird Apple bug
+ #include
#include
#include
#include
***************
*** 48,54 ****
#include
#include
#include
- #include
namespace boost { namespace coroutines {
--- 50,55 ----
diff -cr orig/boost-coroutine/libs/coroutine/example/banana.cpp ./libs/coroutine/example/banana.cpp
*** orig/boost-coroutine/libs/coroutine/example/banana.cpp Sun Aug 20 13:12:02 2006
--- ./libs/coroutine/example/banana.cpp Tue Apr 7 23:40:46 2009
***************
*** 26,35 ****
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <iostream>
#include <string>
#include
- #include
namespace coroutines = boost::coroutines;
using coroutines::coroutine;
--- 26,35 ----
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
+ #include
#include <iostream>
#include <string>
#include
namespace coroutines = boost::coroutines;
using coroutines::coroutine;