Mac OSX 10.4, Carbon.h, boost::shared_ptr, and BOOST_HAS_PTHREADS

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

Rush Manbert wrote:
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.
Two items: 1. What version of Boost are you working with? 2. This post, by me, is likely addressing the problem you are seeing: http://article.gmane.org/gmane.comp.lib.boost.user/12379 We would all be very interested in finding out the answer to the question I pose on that post. Because if the problem is not fixed for the 1.33 release we would have to figure out how to fix it before the release. -- -- Grafik - Don't Assume Anything -- Redshift Software, Inc. - http://redshift-software.com -- rrivera/acm.org - grafik/redshift-software.com -- 102708583/icq - grafikrobot/aim - Grafik/jabber.org

Rene Rivera wrote:
Rush Manbert wrote:
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.
Two items:
1. What version of Boost are you working with?
My version is 1.32 from Darwinports
2. This post, by me, is likely addressing the problem you are seeing:
http://article.gmane.org/gmane.comp.lib.boost.user/12379
We would all be very interested in finding out the answer to the question I pose on that post. Because if the problem is not fixed for the 1.33 release we would have to figure out how to fix it before the release.
There it was, right under my nose. :-) Too recent to be in the archives? Yes, this sounds like exactly the problem I was seeing. I can attempt to test with the 1.33 release candidate. I'll have to figure out how to get it first... - Rush

Rene Rivera wrote:
Two items:
1. What version of Boost are you working with?
2. This post, by me, is likely addressing the problem you are seeing:
http://article.gmane.org/gmane.comp.lib.boost.user/12379
We would all be very interested in finding out the answer to the question I pose on that post. Because if the problem is not fixed for the 1.33 release we would have to figure out how to fix it before the release.
I have gotten the 1.33 RC1 version of Boost and installed it. Using this version, my pthread_mutex_init problems do not occur in the test program, so it looks to me like the problem has been fixed. - Rush

Rush Manbert wrote:
Rene Rivera wrote:
2. This post, by me, is likely addressing the problem you are seeing:
http://article.gmane.org/gmane.comp.lib.boost.user/12379
We would all be very interested in finding out the answer to the question I pose on that post. Because if the problem is not fixed for the 1.33 release we would have to figure out how to fix it before the release.
I have gotten the 1.33 RC1 version of Boost and installed it. Using this version, my pthread_mutex_init problems do not occur in the test program, so it looks to me like the problem has been fixed.
Awesome! Thank you for testing it. -- -- Grafik - Don't Assume Anything -- Redshift Software, Inc. - http://redshift-software.com -- rrivera/acm.org - grafik/redshift-software.com -- 102708583/icq - grafikrobot/aim - Grafik/jabber.org
participants (2)
-
Rene Rivera
-
Rush Manbert