
Hi all, I am writing all of this down because I was only able to find cryptic references to this problem in the Boost archives, and in the Apple Xcode-Users archives. I also want to ask whether my solution to the problem makes sense. I am developing a cross platform static library on OSX 10.4.2 using Xcode 2.1. The Xcode IDE includes a mechanism for unit testing that I am using. The unit test target is setup by Xcode, and one of the things it does is to include Carbon.h as a "prefix include". This means that the compiler command line includes "-include <path>/Carbon.h" and this header file is read BEFORE anything else. Everything had been going great until I wrote a test using boost::shared_ptr. I began to see all sorts of strange behaviors. After a while I turned on Guard Malloc in the debugger. That was when it started catching bad access errors in pthread_mutex_init, which was being called as a result of creating a boost:shared_ptr. It turns out that in the constructor for: template<class P, class D> shared_count(P p, D d) it executes this: pi_ = new sp_counted_base_impl<P, D>(p, d); Class sp_counted_base_impl is derived from sp_counted_base, and sp_counted_base has a data member declared as: #if defined(BOOST_HAS_THREADS) || defined(BOOST_LWM_WIN32) mutable mutex_type mtx_; #endif In the constructor for sp_counted_base, the constructor for mutex_type (lightweight_mutex) was being called. It in turn called pthread_mutex_init, passing the address of its mutex member, which is a 44 byte buffer. The memory access problem, though, is that when operator new called malloc, it did so as if sp_counted_base did NOT contain the mutex data member. This means that the 44 byte buffer wasn't allocated, and because Guard Malloc is very clever, the access outside of the allocated space was caught. I searched around and found messages where people said they saw problems like this because the Carbon headers were included before the Boost headers. This certainly fit my situation. I managed to change the order of header inclusion and everything started working. The class memory was allocated including space for mtx_ and the mutex init worked. This is really a lousy solution, though, so I kept poking around. I put things back so that Carbon.h was included on the command line, and assumed I would need to live with that. I added -DBOOST_HAS_THREADS to my compiler flags. The test still failed because the mutex memory had not been allocated. Because of this, I looked for anywhere where BOOST_HAS_THREADS could be #undef-ed. I found two possibilities, both in boost/config/suffix.hpp. It appeared that in my case BOOST_HAS_PTHREADS was not defined. This led me to boost/config/macos.hpp. I found this little code snippet: // // BSD runtime has pthreads, sigaction, sched_yield and gettimeofday, // of these only pthreads are advertised in <unistd.h>, so set the // other options explicitly: // # define BOOST_HAS_SCHED_YIELD # define BOOST_HAS_GETTIMEOFDAY # define BOOST_HAS_SIGACTION I tried including <unistd.h> ahead of shared_ptr.hpp, but that still failed the same way. I edited macos.hpp and added a fourth #define to this section: # define BOOST_HAS_PTHREADS When I built with the modified header, everything worked as expected. The mutex space was allocated. I don't want to change the Boost headers, though, so undid the change to macos.hpp. I went back to my test target in Xcode and changed the compiler flag -DBOOST_HAS_THREADS to -DBOOST_HAS_PTHREADS. I rebuilt my test code and everything works perfectly. So it *appears* that defining BOOST_HAS_PTHREADS on the compiler command line is the general case solution for this problem, but I'm looking for opinions more expert than mine. If this is indeed true, then does anyone know why the macro isn't just defined in boost/config/platform/macos.hpp? Have I opened myself up to other problems by doing this? Any help would be appreciated. - Rush