faithfracture / Apple-Boost-BuildScript

Script for building Boost for Apple platforms (iOS, iOS Simulator, tvOS, tvOS Simulator, OS X)
279 stars 111 forks source link

Fixed macOS target problem that caused user-config.jam to be ignored, and fixed macOS specific share_ptr crasher caused by using -DBOOST_AC_USE_PTHREADS -DBOOST_SP_USE_PTHREADS. #32

Closed mbendiksen closed 6 years ago

mbendiksen commented 6 years ago

Although the pull request https://github.com/faithfracture/Apple-Boost-BuildScript/pull/22 fixed the macosx-version-min problem, it did not fix the underlying issue discussed and proposed by my https://github.com/faithfracture/Apple-Boost-BuildScript/pull/11 request. Rather than reopening that now pretty stale PR I created a new one.

The issue is that the user-config.jam is not being used at all for macOS target (just add some syntax errors to the macOS user-config.jam and you'll see it doesn't get used). This is because the toolset is set to clang instead of darwin. Additionally, architecture=x86 needs to be passed into b2, then it will find/match and use the user-config.jam.

Once I got that working I ran into a crashing problem that occurs because of shared_ptr being deallocated twice inside of boost thread's destructor. The following code would consistently cause the crash, but will often taken thousands of iterations of the loop (creating and destroying threads) before it occurs:

static void do_nothing () { }

int main()
{
    int thread_count = 0;
    while (true) {
        thread_count++;
        boost::thread t1_thread(boost::bind(&do_nothing));
        if (t1_thread.joinable()) {
            t1_thread.join();
        }
    }
}

I noticed the crash only occurred with the libboost_thread created after the change above (meaning user-config.jam was used). I tracked this down to EXTRA_MACOS_FLAGS having these two flags set: -DBOOST_AC_USE_PTHREADS -DBOOST_SP_USE_PTHREADS. Before I fixed the user-config.jam problem EXTRA_MACOS_FLAGS wasn't being used at all (it is only specified in the .jam file, not the b2 call) which explains why the crash only started occurring after I fixed the .jam issue. My fix for this is to separate out those flags from EXTRA_FLAGS (used by all platforms) to EXTRA_ARM_FLAGS which is only used by the arm based targets. Based on the previous comment those flags were added only for the arm platform: "_Without using the posix thread primitives an invalid compare-and-swap ARM instruction (non-thread-safe) was used for the sharedptr use count causing nasty and subtle bugs." So the crash I was seeing (with code snippet above) isn't the exact same one as reported there – indeed it is the opposite in that it occurs when trying to use pthread_mutex_t for atomic count and shared_ptr locking. I'm not sure why pthread_mutex_t causes the crash on macOS, but empirically (based on code above) it consistently does. Removing -DBOOST_AC_USE_PTHREADS -DBOOST_SP_USE_PTHREADS and letting boost use platform specific locking by default avoids the crash, and shouldn't impact the original reason those flags were added since it was only intended for arm platform targets.

Here is a bit more information where I tracked down the crasher.

faithfracture commented 6 years ago

-DBOOST_SP_USE_PTHREADS is the define that tells Boost to use Pthreads for shared_ptr (hence the _SP_ part). -DBOOST_AC_USE_PTHREADS is for shared pointer atomic count. I'm sure they're probably both related, but just thought I'd comment on that.

This seems fine to me. My projects are all iOS & tvOS. I don't actually use the macOS build for anything other than running some shared library unit tests, but nothing that is in production. If this is working for you then I'm OK with it.

Please update the changelog though :)

mbendiksen commented 6 years ago

Changelog updated.