Is it possible to enable _LIBCPP_DEBUG2 in the current Xcode 4.6.1 toolchain on Mountain Lion?

StackOverflow https://stackoverflow.com/questions/15899937

  •  02-04-2022
  •  | 
  •  

This thread is an early discussion of a debug mode for clang's libc++ that was to be enabled by defining _LIBCPP_DEBUG2 in the compiler command. Having just done battle with a mis-allocated std::vector<> I am interested in being able to turn this on for my debug builds.

When I try simply adding _LIBCPP_DEBUG=1 to the Preprocessor Macros build settings, I get errors during the link phase (shown below). I suspect these are caused by newly-generated references to the debug database described in the discussion thread.

In that early discussion, it was stated that the necessary support was present in the standard version of the library, but today this seems not to be the case. Is it still supported at all? And if so, how to I link to the necessary bits?

Ld /Users/kaelin/Library/Developer/Xcode/DerivedData/OMWorkspace-bzkzcamyqoztgyalubrmemkzmjvk/Build/Products/Debug/vMAT.dylib normal x86_64
    cd /Users/Shared/Source/vMAT
    setenv MACOSX_DEPLOYMENT_TARGET 10.8
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch x86_64 -dynamiclib -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk -L/Users/kaelin/Library/Developer/Xcode/DerivedData/OMWorkspace-bzkzcamyqoztgyalubrmemkzmjvk/Build/Products/Debug -F/Users/kaelin/Library/Developer/Xcode/DerivedData/OMWorkspace-bzkzcamyqoztgyalubrmemkzmjvk/Build/Products/Debug -F/Users/Shared/Source/vMAT/../../../kaelin/Library/Developer/Xcode/DerivedData/OMWorkspace-bzkzcamyqoztgyalubrmemkzmjvk/Build/Products/Debug -filelist /Users/kaelin/Library/Developer/Xcode/DerivedData/OMWorkspace-bzkzcamyqoztgyalubrmemkzmjvk/Build/Intermediates/vMAT.build/Debug/vMAT.build/Objects-normal/x86_64/vMAT.LinkFileList -install_name "@rpath/vMAT.dylib" -mmacosx-version-min=10.8 -fobjc-arc -fobjc-link-runtime -stdlib=libc++ -framework BlocksKit -framework Accelerate -framework Cocoa -single_module -compatibility_version 1 -current_version 1 -o /Users/kaelin/Library/Developer/Xcode/DerivedData/OMWorkspace-bzkzcamyqoztgyalubrmemkzmjvk/Build/Products/Debug/vMAT.dylib

Undefined symbols for architecture x86_64:
  "std::__1::__libcpp_db::__comparable(void const*, void const*) const", referenced from:
      NSString* (anonymous namespace)::dump<double>(NSString*, double*, int vector[4]) in vMAT_Array+UnaryOps.o
      NSString* (anonymous namespace)::dump<float>(NSString*, float*, int vector[4]) in vMAT_Array+UnaryOps.o
      signed char (anonymous namespace)::isEqualEpsilon<double>(double*, int vector[4], double*, int vector[4], double) in vMAT_Array+BinaryOps.o
      signed char (anonymous namespace)::isEqualEpsilon<float>(float*, int vector[4], float*, int vector[4], double) in vMAT_Array+BinaryOps.o
  "std::__1::__libcpp_db::__dereferenceable(void const*) const", referenced from:
      NSString* (anonymous namespace)::dump<double>(NSString*, double*, int vector[4]) in vMAT_Array+UnaryOps.o
      NSString* (anonymous namespace)::dump<float>(NSString*, float*, int vector[4]) in vMAT_Array+UnaryOps.o
      signed char (anonymous namespace)::isEqualEpsilon<double>(double*, int vector[4], double*, int vector[4], double) in vMAT_Array+BinaryOps.o
      signed char (anonymous namespace)::isEqualEpsilon<float>(float*, int vector[4], float*, int vector[4], double) in vMAT_Array+BinaryOps.o
  "std::__1::__libcpp_db::__insert_c(void*)", referenced from:
      std::__1::vector<float, std::__1::allocator<float> >::vector<float*>(float*, float*, std::__1::enable_if<__is_forward_iterator<float*>::value, void>::type*) in vMAT_Array+UnaryOps.o
      std::__1::vector<double, std::__1::allocator<double> >::vector<double*>(double*, double*, std::__1::enable_if<__is_forward_iterator<double*>::value, void>::type*) in vMAT_Array+UnaryOps.o
      std::__1::vector<float, std::__1::allocator<float> >::vector<float*>(float*, float*, std::__1::enable_if<__is_forward_iterator<float*>::value, void>::type*) in vMAT_Array+BinaryOps.o
      std::__1::vector<double, std::__1::allocator<double> >::vector<double*>(double*, double*, std::__1::enable_if<__is_forward_iterator<double*>::value, void>::type*) in vMAT_Array+BinaryOps.o
      std::__1::vector<int, std::__1::allocator<int> >::vector(unsigned long, int const&) in vMAT_inconsistent.o
      std::__1::vector<int, std::__1::allocator<int> >::vector(std::__1::vector<int, std::__1::allocator<int> > const&) in vMAT_inconsistent.o
      (anonymous namespace)::clusterOptions(NSArray*) in vMAT_cluster.o
      ...
  "std::__1::__libcpp_db::__insert_ic(void*, void const*)", referenced from:
      NSString* (anonymous namespace)::dump<double>(NSString*, double*, int vector[4]) in vMAT_Array+UnaryOps.o
      NSString* (anonymous namespace)::dump<float>(NSString*, float*, int vector[4]) in vMAT_Array+UnaryOps.o
      signed char (anonymous namespace)::isEqualEpsilon<double>(double*, int vector[4], double*, int vector[4], double) in vMAT_Array+BinaryOps.o
      signed char (anonymous namespace)::isEqualEpsilon<float>(float*, int vector[4], float*, int vector[4], double) in vMAT_Array+BinaryOps.o
  "std::__1::__libcpp_db::__erase_c(void*)", referenced from:
      NSString* (anonymous namespace)::dump<double>(NSString*, double*, int vector[4]) in vMAT_Array+UnaryOps.o
      NSString* (anonymous namespace)::dump<float>(NSString*, float*, int vector[4]) in vMAT_Array+UnaryOps.o
      signed char (anonymous namespace)::isEqualEpsilon<double>(double*, int vector[4], double*, int vector[4], double) in vMAT_Array+BinaryOps.o
      signed char (anonymous namespace)::isEqualEpsilon<float>(float*, int vector[4], float*, int vector[4], double) in vMAT_Array+BinaryOps.o
      (anonymous namespace)::traceTree(vMAT::Matrix<double>, double*, int, unsigned int) in vMAT_inconsistent.o
      ___Block_byref_object_dispose_ in vMAT_inconsistent.o
      (anonymous namespace)::Options::~Options() in vMAT_cluster.o
      ...
  "std::__1::__libcpp_db::__erase_i(void*)", referenced from:
      NSString* (anonymous namespace)::dump<double>(NSString*, double*, int vector[4]) in vMAT_Array+UnaryOps.o
      NSString* (anonymous namespace)::dump<float>(NSString*, float*, int vector[4]) in vMAT_Array+UnaryOps.o
      signed char (anonymous namespace)::isEqualEpsilon<double>(double*, int vector[4], double*, int vector[4], double) in vMAT_Array+BinaryOps.o
      signed char (anonymous namespace)::isEqualEpsilon<float>(float*, int vector[4], float*, int vector[4], double) in vMAT_Array+BinaryOps.o
  "std::__1::__get_const_db()", referenced from:
      NSString* (anonymous namespace)::dump<double>(NSString*, double*, int vector[4]) in vMAT_Array+UnaryOps.o
      NSString* (anonymous namespace)::dump<float>(NSString*, float*, int vector[4]) in vMAT_Array+UnaryOps.o
      signed char (anonymous namespace)::isEqualEpsilon<double>(double*, int vector[4], double*, int vector[4], double) in vMAT_Array+BinaryOps.o
      signed char (anonymous namespace)::isEqualEpsilon<float>(float*, int vector[4], float*, int vector[4], double) in vMAT_Array+BinaryOps.o
  "std::__1::__c_node::~__c_node()", referenced from:
      std::__1::_C_node<std::__1::vector<float, std::__1::allocator<float> > >::~_C_node() in vMAT_Array+UnaryOps.o
      std::__1::_C_node<std::__1::vector<double, std::__1::allocator<double> > >::~_C_node() in vMAT_Array+UnaryOps.o
      std::__1::_C_node<std::__1::vector<float, std::__1::allocator<float> > >::~_C_node() in vMAT_Array+BinaryOps.o
      std::__1::_C_node<std::__1::vector<double, std::__1::allocator<double> > >::~_C_node() in vMAT_Array+BinaryOps.o
      std::__1::_C_node<std::__1::vector<int, std::__1::allocator<int> > >::~_C_node() in vMAT_inconsistent.o
      std::__1::_C_node<std::__1::vector<int, std::__1::allocator<int> > >::~_C_node() in vMAT_cluster.o
      std::__1::_C_node<std::__1::vector<double, std::__1::allocator<double> > >::~_C_node() in vMAT_cluster.o
      ...
  "std::__1::__get_db()", referenced from:
      NSString* (anonymous namespace)::dump<double>(NSString*, double*, int vector[4]) in vMAT_Array+UnaryOps.o
      NSString* (anonymous namespace)::dump<float>(NSString*, float*, int vector[4]) in vMAT_Array+UnaryOps.o
      std::__1::vector<float, std::__1::allocator<float> >::vector<float*>(float*, float*, std::__1::enable_if<__is_forward_iterator<float*>::value, void>::type*) in vMAT_Array+UnaryOps.o
      std::__1::vector<double, std::__1::allocator<double> >::vector<double*>(double*, double*, std::__1::enable_if<__is_forward_iterator<double*>::value, void>::type*) in vMAT_Array+UnaryOps.o
      signed char (anonymous namespace)::isEqualEpsilon<double>(double*, int vector[4], double*, int vector[4], double) in vMAT_Array+BinaryOps.o
      signed char (anonymous namespace)::isEqualEpsilon<float>(float*, int vector[4], float*, int vector[4], double) in vMAT_Array+BinaryOps.o
      std::__1::vector<float, std::__1::allocator<float> >::vector<float*>(float*, float*, std::__1::enable_if<__is_forward_iterator<float*>::value, void>::type*) in vMAT_Array+BinaryOps.o
      ...
  "typeinfo for std::__1::__c_node", referenced from:
      typeinfo for std::__1::_C_node<std::__1::vector<float, std::__1::allocator<float> > > in vMAT_Array+UnaryOps.o
      typeinfo for std::__1::_C_node<std::__1::vector<double, std::__1::allocator<double> > > in vMAT_Array+UnaryOps.o
      typeinfo for std::__1::_C_node<std::__1::vector<float, std::__1::allocator<float> > > in vMAT_Array+BinaryOps.o
      typeinfo for std::__1::_C_node<std::__1::vector<double, std::__1::allocator<double> > > in vMAT_Array+BinaryOps.o
      typeinfo for std::__1::_C_node<std::__1::vector<int, std::__1::allocator<int> > > in vMAT_inconsistent.o
      typeinfo for std::__1::_C_node<std::__1::vector<int, std::__1::allocator<int> > > in vMAT_cluster.o
      typeinfo for std::__1::_C_node<std::__1::vector<double, std::__1::allocator<double> > > in vMAT_cluster.o
      ...
  "vtable for std::__1::__c_node", referenced from:
      std::__1::_C_node<std::__1::vector<float, std::__1::allocator<float> > >::_C_node(void*, std::__1::__c_node*) in vMAT_Array+UnaryOps.o
      std::__1::_C_node<std::__1::vector<double, std::__1::allocator<double> > >::_C_node(void*, std::__1::__c_node*) in vMAT_Array+UnaryOps.o
      std::__1::_C_node<std::__1::vector<float, std::__1::allocator<float> > >::_C_node(void*, std::__1::__c_node*) in vMAT_Array+BinaryOps.o
      std::__1::_C_node<std::__1::vector<double, std::__1::allocator<double> > >::_C_node(void*, std::__1::__c_node*) in vMAT_Array+BinaryOps.o
      std::__1::_C_node<std::__1::vector<int, std::__1::allocator<int> > >::_C_node(void*, std::__1::__c_node*) in vMAT_inconsistent.o
      std::__1::_C_node<std::__1::vector<int, std::__1::allocator<int> > >::_C_node(void*, std::__1::__c_node*) in vMAT_cluster.o
      std::__1::_C_node<std::__1::vector<double, std::__1::allocator<double> > >::_C_node(void*, std::__1::__c_node*) in vMAT_cluster.o
      ...
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
有帮助吗?

解决方案

According to this conversation,

Thanks Chris. I've checked in an experimental implementation of this.

-D_LIBCPP_DEBUG2

gets you the "standard" debugging mode, which includes checking for iterator invalidation.

-D_LIBCPP_DEBUG2=0

gets you "debug lite". This only checks things that are really cheap such as those you mention.

I've left the door open for:

-D_LIBCPP_DEBUG2=2

which would make even more expensive checks (e.g. check the invariants of a red/black tree). But that isn't done at this point.

I'm still concentrating only on vector at this point.

Howard

When I tried this flag with Xcode 5.0.x (current most recent version of Xcode), _LIBCPP_DEBUG2=1 didn't work because it needs linking to the libcpp's debugging support runtime code which is specially written to debug libcpp itself. But _LIBCPP_DEBUG2=0 is working without linking to the debugging support runtime, and currently providing me very useful assertions such as calling std::vector<T>::back() on empty vector.

其他提示

Just to update this: the following seems to work and catch at least the main errors you want to catch on 10.9:

-D_LIBCPP_DEBUG=0

Anything higher than level 0 appears to be unsupported out of the box for clang++ in 10.9

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top