是否可以在 Mountain Lion 上的当前 Xcode 4.6.1 工具链中启用 _LIBCPP_DEBUG2?

Posted

技术标签:

【中文标题】是否可以在 Mountain Lion 上的当前 Xcode 4.6.1 工具链中启用 _LIBCPP_DEBUG2?【英文标题】:Is it possible to enable _LIBCPP_DEBUG2 in the current Xcode 4.6.1 toolchain on Mountain Lion? 【发布时间】:2013-04-09 10:50:50 【问题描述】:

This thread 是对 clang 的 libc++ 调试模式的早期讨论,通过在编译器命令中定义 _LIBCPP_DEBUG2 来启用它。刚刚与分配错误的 std::vector<> 进行了斗争,我有兴趣为我的调试版本打开它。

当我尝试简单地将 _LIBCPP_DEBUG=1 添加到 预处理器宏 构建设置时,我在链接阶段遇到错误(如下所示)。我怀疑这些是由讨论线程中描述的新生成的对调试数据库的引用引起的。

在早期的讨论中,据说标准版本的库中提供了必要的支持,但今天似乎并非如此。它仍然支持吗?如果是这样,我如何链接到必要的位?

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)

【问题讨论】:

【参考方案1】:

根据this conversation,

谢谢克里斯。我已经检查了这个的实验性实现。

-D_LIBCPP_DEBUG2

为您提供“标准”调试模式,其中包括检查 迭代器失效。

-D_LIBCPP_DEBUG2=0

让您“调试精简版”。这只检查真正便宜的东西 比如你提到的那些。

我已经把门打开了:

-D_LIBCPP_DEBUG2=2

这将进行更昂贵的检查(例如检查不变量 红/黑树)。但目前还没有这样做。

此时我仍然只专注于矢量。

霍华德

当我使用 Xcode 5.0.x(当前最新版本的 Xcode)尝试使用此标志时,_LIBCPP_DEBUG2=1 不起作用,因为它需要链接到 libcpp 的调试支持运行时代码,该代码专门用于调试 libcpp 本身。但是_LIBCPP_DEBUG2=0 在没有链接到调试支持运行时的情况下工作,并且目前为我提供了非常有用的断言,例如在空向量上调用std::vector&lt;T&gt;::back()

【讨论】:

【参考方案2】:

只是为了更新这一点:以下似乎有效,并且至少可以捕获您希望在 10.9 上捕获的主要错误:

-D_LIBCPP_DEBUG=0

10.9 中的 clang++ 似乎不支持任何高于 0 级的内容

【讨论】:

遗憾的是,_LIBCPP_DEBUG=1 在 XCode 11.6 中似乎仍然不受支持,因为它出现未定义的符号链接器错误。有关更多详细信息,请参阅my answer 相关问题。

以上是关于是否可以在 Mountain Lion 上的当前 Xcode 4.6.1 工具链中启用 _LIBCPP_DEBUG2?的主要内容,如果未能解决你的问题,请参考以下文章

Safari Lion/Mountain Lion 上的 Canvas to Video 非常慢

如何为 OSX Mountain Lion 上的应用程序设置环境变量?

用于向Mountain Lion中的通知中心发送通知的命令行实用程序

在 Mountain Lion 上使用 Homebrew 安装 mcrypt 支持 php54 的问题

错误:MongoDB:未知版本:mountain_lion

我可以让 Java 在 Mountain Lion 下打印到控制台吗?