Crash in std::runtime_error destructor when linking with TBB and libc++ on Mac OS X

Crash in std::runtime_error destructor when linking with TBB and libc++ on Mac OS X

neilhenderson's picture

I'm evaluating the commercial version of TBB with Intel Composer XE 2013 on Mac OS X 10.8.3.

My application is built with clang and needs to link with libc++.  When I also link in TBB (debug or release dylib) the application crashes whenever it tries to destruct a std::runtime_error exception that it previously constructed (doesn't need to throw it).

The crash occurs because the runtime_error destructor in libstdc++ is incorrectly being executed instead of the one in libc++ that my application linked with.

Please note that this is not an ABI incompatibility problem due to using libc++ and libstdc++ in the same process.  I'm not throwing the exception (or passing any other library type) across module boundaries.

The libtbb that is bundled with Composer XE 2013 appears to be built with gcc and depends on libstdc++.  The problem appears to be that the dynamic linker loads TBB and hence libstdc++ but then resolves the std::runtime_error destructor from libstdc++ instead of the one in libc++.  Since the runtime_error object was constructed using libc++ and then attempts to destruct using libstdc++, it's not surprising that a crash occurs since the implementations are different.

I can only reproduce the problem with std::runtime_error.  Destructing other exceptions (including ones derived from runtime_error) work fine.  In addition, I can only reproduce the problem when linking TBB.  I tried to create my own shared library that mimics what TBB is doing (and depends on libstdc++) but that worked fine.

Here is a sample program that reproduces the problem:

#include <stdexcept>
#include <iostream>
int main()
{
 {
 std::runtime_error rt("hi");
 std::cout << rt.what() << std::endl;
 }
 // Crash at end of scope when rt destructs
 return 0;
}

Build it like this:

$ clang -v
Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.3.0
Thread model: posix

TBB=/opt/intel/composer_xe_2013.1.119/tbb/lib/libtbb.dylib
clang++ -stdlib=libc++ myprog.cpp $TBB -o myprog
./myprog

This is the output:

hi
myprog(2226) malloc: *** error for object 0x7feb694039ec: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6 ./myprog

If you run under a debugger you'll see the following stack trace:

0 __kill 0x7fff8754bd46 
1 abort 0x7fff87472df0 
2 free 0x7fff874469b9 
3 std::runtime_error::~runtime_error 0x7fff8d425526 
4 main 0x1000011b7

The address of the runtime_error destructor matches that of libstdc++ instead of the one in libc++.

One obvious solution would be to use a version of TBB that depends on libc++ instead of libstdc++.  Is there a commercial version of TBB available built with libc++?

I'd appreciate any advice or workarounds.

3 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
Anton Potapov (Intel)'s picture

as a temporary workaround you can build TBB from sources via clang with libc++ instead of libstdc++ via following make command

make compiler=clang stdlib=libc++ 

see build\index.hml in source distrubiotn for more details 

 

neilhenderson's picture

Thanks for your reply, Anton.

If I purchase a commercial license, can I then build TBB from the open source code (with clang/libc++ like you describe) and distribute it as part of my application, but under the conditions of a commercial license?

Alternatively, is there going to be a clang/libc++ version of TBB included with the commercial distribution anytime soon?

Thanks,

Neil

Login to leave a comment.