|
Boost Users : |
Subject: [Boost-users] [coroutine] Bus error on Mac OS X 10.5
From: Nat Goodspeed (nat_at_[hidden])
Date: 2009-03-27 22:20:56
I've downloaded the not-yet-Boost coroutine library [1] from the Boost
Vault [2]. On a couple of Linux platforms I was able to build and run
example/banana.cpp -- though I had to patch noreturn.hpp for gcc 3.3 [3].
On an Intel "fall 2008" MacBook Pro running OS X 10.5.6, with Apple gcc
4.0.1, I had to comment out the MAP_ANONYMOUS mmap() flag [4] -- I don't
think that flag is available in Darwin. (Obviously that patch should
test for MAP_ANONYMOUS rather than simply suppressing it.)
Having done that, 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 [5] in which Kevin Van
Vechten recommends #defining _XOPEN_SOURCE before #include <ucontext.h>:
>> 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.
Unfortunately, adding such a #define [6] does not resolve my bus error.
The article [7] in which I found ref [5] proposes a classic-C program
[8] to illustrate use of getcontext() and swapcontext(). On my Mac, that
program produces a seg fault with or without #define _XOPEN_SOURCE. So
my apologies: this may very well not be a Boost issue, or even a
pre-Boost issue.
I'm very excited to try the coroutine library, but crashing on Macs is a
show-stopper for us. Has anyone else succeeded in running it on a Mac?
[1] http://www.crystalclearsoftware.com/soc/coroutine/index.html
[2]
http://www.boostpro.com/vault/index.php?action=downloadfile&filename=boost-coroutine.tar.gz&directory=Concurrent%20Programming&
[3] attached boost-coroutine.gcc33.patch
[4] attached boost-coroutine.osx-mmap.patch
[5] http://lists.apple.com/archives/darwin-dev/2008/Jan/msg00232.html
[6] attached boost-coroutine.osx-context.patch
[7] http://hjiang.net/archives/220
[8] attached swapcontext_test.c
*** boost/coroutine/detail/noreturn.hpp~ Sun Aug 20 10:11:09 2006
--- boost/coroutine/detail/noreturn.hpp Fri Mar 27 17:00:00 2009
***************
*** 40,48 ****
--- 40,54 ----
#if defined(__GNUC__)
+ #if __GNUC_MAJOR__ > 3 || (__GNUC_MAJOR__ == 3 && __GNUC_MINOR__ > 3)
#define BOOST_COROUTINE_NORETURN(function) \
function __attribute__((__noreturn__)) \
/**/
+ #else // gcc 3.3
+ #define BOOST_COROUTINE_NORETURN(function) \
+ function
+ /**/
+ #endif // gcc 3.3
#elif defined (BOOST_MSVC)
*** boost/coroutine/detail/posix_utility.hpp~ Sun Aug 20 13:11:09 2006
--- boost/coroutine/detail/posix_utility.hpp Fri Mar 27 18:52:17 2009
***************
*** 129,135 ****
void * stack = ::mmap(NULL,
size,
PROT_EXEC|PROT_READ|PROT_WRITE,
! MAP_PRIVATE|MAP_ANONYMOUS,
-1,
0
);
--- 129,135 ----
void * stack = ::mmap(NULL,
size,
PROT_EXEC|PROT_READ|PROT_WRITE,
! MAP_PRIVATE /*|MAP_ANONYMOUS*/,
-1,
0
);
*** boost/coroutine/detail/context_posix.hpp~ Sun Aug 20 13:11:09 2006
--- boost/coroutine/detail/context_posix.hpp Fri Mar 27 20:57:44 2009
***************
*** 42,47 ****
--- 42,56 ----
* NOTE2: makecontext and friends are declared obsolescent in SuSv3, but
* it is unlikely that they will be removed any time soon.
*/
+ // NOTE3 (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.
+ // [While we could make that OSX-specific, it seems harmless enough?]
+ #ifndef _XOPEN_SOURCE
+ #define _XOPEN_SOURCE
+ #endif
#include <ucontext.h>
#include <boost/noncopyable.hpp>
#include <boost/coroutine/exception.hpp>
// From http://hjiang.net/archives/220
#include <signal.h>
#include <stdio.h>
// 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.
// [While we could make that OSX-specific, it seems harmless enough?]
#ifndef _XOPEN_SOURCE
//#define _XOPEN_SOURCE
#endif
#include <ucontext.h>
// Signals which routine should run.
volatile int g_turn;
void routineOne(ucontext_t* self, ucontext_t* other) {
int numbers[] = {1, 2, 3};
int i;
for (i = 0; i < sizeof(numbers)/sizeof(int); ++i) {
printf("Routine one: %d\n", numbers[i]);
// Call other with current continuation
if (g_turn != 1) {
g_turn = 1;
swapcontext(self, other);
}
}
}
void routineTwo(ucontext_t* self, ucontext_t* other) {
int numbers[] = {-1, -2, -3};
int i;
for (i = 0; i < sizeof(numbers)/sizeof(int); ++i) {
printf("Routine two: %d\n", numbers[i]);
if (g_turn != 2) {
g_turn = 2;
swapcontext(self, other);
}
}
}
int main() {
// Continuations
ucontext_t cont_one;
ucontext_t cont_two;
ucontext_t cont_main;
// one stack for each thread
char stack_one[SIGSTKSZ];
char stack_two[SIGSTKSZ];
// Initialize the coutinuations.
cont_one.uc_link = &cont_main;
cont_one.uc_stack.ss_sp = stack_one;
cont_one.uc_stack.ss_size = sizeof(stack_one);
cont_two.uc_link = &cont_main;
cont_two.uc_stack.ss_sp = stack_two;
cont_two.uc_stack.ss_size = sizeof(stack_two);
getcontext(&cont_one);
makecontext(&cont_one, (void (*)())routineOne, 2, &cont_one, &cont_two);
getcontext(&cont_two);
makecontext(&cont_two, (void (*)())routineTwo, 2, &cont_two, &cont_one);
g_turn = 0;
// Call routineOne with current continuation. Continue from here
// after routineOne finishes.
getcontext(&cont_main);
if (g_turn == 0) {
setcontext(&cont_one);
}
return 0;
}
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net