Opened 9 years ago

Last modified 8 years ago

#9118 reopened Bugs

Seg fault on thread join when llvm and libc++ are used

Reported by: tconant@… Owned by: viboes
Milestone: To Be Determined Component: thread
Version: Boost 1.54.0 Severity: Problem
Keywords: Cc:

Description (last modified by viboes)

This issue appears to be specific to llvm libc++ standard library

the program compiled with the following options will have a seg fault on thread join.

clang -x c++ -arch x86_64 -std=gnu++11 -stdlib=libc++ -I/opt/local/include -c main.cpp -o main.o
clang++ -arch x86_64  -L/opt/local/lib  main.o -stdlib=libc++ -lboost_system-mt -lboost_thread-mt -o mutex_test

the program compiled with

clang -x c++ -arch x86_64 -I/opt/local/include -c main.cpp -o main.o
clang++ -arch x86_64  -L/opt/local/lib  main.o -lboost_system-mt -lboost_thread-mt -o mutex_test
System Version :  OS X Mountain Lion 10.8.4
Compiler :
$ clang --version
Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.4.0
Thread model: posix
Boost: built/installed with mac ports

Attachments (1)

main.cpp (228 bytes ) - added by gosuperninja@… 9 years ago.

Download all attachments as: .zip

Change History (21)

by gosuperninja@…, 9 years ago

Attachment: main.cpp added

comment:1 by anonymous, 9 years ago

The description got messed up when I copied and pasted it in

The following generates an executable that will seg fault.

clang -x c++ -arch x86_64 -std=gnu++11 -stdlib=libc++ -I/opt/local/include -c main.cpp -o main.o
clang++ -arch x86_64 -L/opt/local/lib main.o -stdlib=libc++ -lboost_system-mt -lboost_thread-mt -o mutex_test

The following will generate an executable that will not seg fault

clang -x c++ -arch x86_64 -I/opt/local/include -std=gnu++11 -c main.cpp -o main.o
clang++ -arch x86_64  -L/opt/local/lib  main.o -lboost_system-mt -lboost_thread-mt -o mutex_test

comment:2 by anonymous, 9 years ago

Here is a the backtrace :

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000001
0x000000010002df45 in boost::detail::thread_data_base::~thread_data_base ()
(gdb) bt
#0  0x000000010002df45 in boost::detail::thread_data_base::~thread_data_base ()
#1  0x0000000100004c15 in boost::detail::thread_data<boost::_bi::bind_t<void, void (*)(), boost::_bi::list0> >::~thread_data ()
#2  0x0000000100003b05 in boost::detail::thread_data<boost::_bi::bind_t<void, void (*)(), boost::_bi::list0> >::~thread_data ()
#3  0x0000000100003b29 in boost::detail::thread_data<boost::_bi::bind_t<void, void (*)(), boost::_bi::list0> >::~thread_data ()
#4  0x0000000100005aee in boost::checked_delete<boost::detail::thread_data<boost::_bi::bind_t<void, void (*)(), boost::_bi::list0> > > ()
#5  0x0000000100005be9 in boost::detail::sp_counted_impl_p<boost::detail::thread_data<boost::_bi::bind_t<void, void (*)(), boost::_bi::list0> > >::dispose ()
#6  0x000000010002e9bf in boost::thread::join_noexcept ()
#7  0x00000001000019a4 in boost::thread::join ()
#8  0x0000000100000d45 in main ()
(gdb) 

comment:3 by viboes, 9 years ago

Description: modified (diff)
Owner: changed from Anthony Williams to viboes
Status: newassigned

comment:4 by viboes, 9 years ago

Do you get the same error if you change

    boost::thread t1 (boost::bind( &do_nothing));

by

    boost::thread t1 ( &do_nothing );

comment:5 by viboes, 9 years ago

Component: threadsthread

comment:6 by viboes, 9 years ago

The same program works on trunk

clang-darwin.compile.c++ ../../../bin.v2/libs/thread/test/clang_main.test/clang-darwin-g3.2x/release/threading-multi/clang_main.o

    "/Users/viboes/clang/clang+llvm-3.2-x86_64-apple-darwin11/bin/clang++" -x c++ -arch x86_64 -std=gnu++11 -O3 -Wextra -Wno-long-long -Wunused-function -pedantic -O3 -finline-functions -Wno-inline -Wall -pedantic -DBOOST_ALL_NO_LIB=1 -DBOOST_CHRONO_DYN_LINK=1 -DBOOST_SYSTEM_DYN_LINK=1 -DBOOST_SYSTEM_NO_DEPRECATED -DBOOST_THREAD_BUILD_DLL=1 -DBOOST_THREAD_POSIX -DBOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED -DBOOST_THREAD_USE_DLL=1 -DNDEBUG -I"../../.." -c -o "../../../bin.v2/libs/thread/test/clang_main.test/clang-darwin-g3.2x/release/threading-multi/clang_main.o" "clang_main.cpp"

clang-darwin.link ../../../bin.v2/libs/thread/test/clang_main.test/clang-darwin-g3.2x/release/threading-multi/clang_main

    "/Users/viboes/clang/clang+llvm-3.2-x86_64-apple-darwin11/bin/clang++"   -o "../../../bin.v2/libs/thread/test/clang_main.test/clang-darwin-g3.2x/release/threading-multi/clang_main" "../../../bin.v2/libs/thread/test/clang_main.test/clang-darwin-g3.2x/release/threading-multi/clang_main.o" "../../../bin.v2/libs/chrono/build/clang-darwin-g3.2x/release/threading-multi/libboost_chrono.dylib" "../../../bin.v2/libs/thread/build/clang-darwin-g3.2x/release/threading-multi/libboost_thread.dylib" "../../../bin.v2/libs/system/build/clang-darwin-g3.2x/release/threading-multi/libboost_system.dylib"    -arch x86_64 -std=gnu++11
Mac OS X Lion 10.7.5 (11G63)

/Users/viboes/clang/clang+llvm-3.2-x86_64-apple-darwin11/bin/clang++ --version
clang version 3.2 (tags/RELEASE_32/final)
Target: x86_64-apple-darwin11.4.2
Thread model: posix

comment:7 by viboes, 9 years ago

Summary: Seg fault on thread joinSeg fault on thread join when llvm and libc++ are used

comment:8 by viboes, 9 years ago

Resolution: duplicate
Status: assignedclosed

Isn't this a duplicate of #7666?

comment:9 by viboes, 9 years ago

With which options was built Boost?

What is the size of boost::detail::thread_data_base on each case?

Last edited 9 years ago by viboes (previous) (diff)

comment:10 by viboes, 9 years ago

I suspect that this is related to an ABI incompatibility.

comment:11 by markus.weber@…, 9 years ago

We've recently run into this problem as well and have been able to tie it to the use of pragma pack(...).

The same code runs smooth on Windows, but fails on Mac in one case but works in another place. We noticed that we can provoke the failure by deliberately setting a structure packing != 8 before include boost/thread.hpp, e.g. #pragma pack(1).

Amazingly the code also fails if we explicitly switch back to default packing prior to the include (#pragma pack()).

It only seems to work if we explicitly sett the packing to 8 prior to the include.

This seems to indicate a missing pack statement somewhere in the platform specific code, which would also explain why most parties cannot reproduce it, while some can, and the code is not susceptible to any specific packing statement on Windows.

I should note that we also had the impression that #pragma pack(x) does not seem to work reliable on GCC, as we saw complaints in other code as well.

in reply to:  11 ; comment:12 by anonymous, 9 years ago

Replying to markus.weber@…:

It only seems to work if we explicitly sett the packing to 8 prior to the include.

That indeed solves the problem. Added #pragma pack(8) just before first include file in boost/boost/thread.hpp

However its a temporary workaround and not a proper fix. Very much looking forward for a proper fix (a proper location for pragma statement to go or something similar). Reproducible on MacOSX 10.8.5 using CLang compiler (Xcode 5) built with stdc++98 and libstdc++

in reply to:  12 comment:13 by anonymous, 9 years ago

Replying to anonymous:

Replying to markus.weber@…:

It only seems to work if we explicitly sett the packing to 8 prior to the include.

That indeed solves the problem. Added #pragma pack(8) just before first include file in boost/boost/thread.hpp

Looks like an oversight. With this change crash did not come up once and thought that is solved. But upon successive builds, its back to square one!

comment:14 by markus.weber@…, 9 years ago

For what it is worth: We were initially slow in discovering this issue as we developed the code on Windows first - and there the problem does not show. I tend to interpret this as a missing pack statement in one of the platform-specific headers. Shouldn't be that difficult to find if you know exactly what you are doing as there is not all *that* much going into the control structure which gets corrupted. For someone who knows the code intimately it should not be a hard challenge.

comment:15 by viboes, 9 years ago

Resolution: duplicate
Status: closedreopened

Please reopen the ticket next time if you want that I follow up it.

I will take a look at as soon as I have some time.

Last edited 9 years ago by viboes (previous) (diff)

comment:16 by viboes, 8 years ago

I have take a look and I don't see where the pack is needed. Any idea?

in reply to:  16 comment:17 by anonymous, 8 years ago

Given the long lead-time I am working from memory here: At the time I investigated this I did really dive way into the control structures, but I don't recall all the details anymore. Some of the members in there are platform-dependent. I tried to locate them but they turned out to be quite involved and hard to back-trace if you don't know them by heart - that's why I gave up when we found the pack(8) work-around, leaving this to someone who knows them better than me.

So the short answer is: No, I have no better idea.

comment:18 by viboes, 8 years ago

The back-trace call 3 times to ~thread_data. This is weird. Are you sure that you have created a single thread?

Are you able to reproduce it now?

comment:19 by markus.weber@…, 8 years ago

I had one of our engineers verify this. We have switched to version 1.55 since reporting this issue and we positively verified it to be still present. In the test scenario (part of the standard regression tests) multiple threads may be running, but this is the only one created and maintained by boost. Please let me know if this might be a problem source. During original verification we wrote some short test which only created the thread and terminated it immediately again (nothing else running).

comment:20 by viboes, 8 years ago

Do you mean that the backtrace doesn't corresponds to the example?

Note: See TracTickets for help on using tickets.