1

When reading the std library implementation I could see lots of checks enabled by #if _LIBCPP_DEBUG_LEVEL >= 2 conditions. I tried to add _LIBCPP_DEBUG_LEVEL = 3 in xcode preprocessor options, but <iterator> doesn't compile anymore:

#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_i(this);   <----- the error is on this line
#endif

Is there something else I'm missing here to use a higher debug level for the standard library?

Mircea Ispas
  • 20,260
  • 32
  • 123
  • 211
  • What's the error you get? – Almo Feb 16 '15 at 15:40
  • Seems like libc++ "Debug Mode" is still not entirely functional in XCode 11.1. I was able to get a library to compile and link with `#define _LIBCPP_DEBUG_LEVEL 2` and `#define _LIBCPP_CONSTEXPR_IF_NODEBUG` in a file (with inconsistent behavior between code in different files) but as soon as I try that in a `main.cpp` or via the XCode Preprocessor Macros setting, I get undefined symbol link errors like to "std::__1::__libcpp_db::__dereferenceable(void const*) const". Were link errors what you had seen or did it not use to get even that far? – Louis Langholtz Aug 25 '20 at 17:15
  • Tried XCode 11.6 now and still have undefined symbols. Discovered though that defining `_LIBCPP_DEBUG=1` alone makes the `__config` include file define `_LIBCPP_DEBUG_LEVEL=2` and setting `_LIBCPP_CONSTEXPR_IF_NODEBUG=` was no longer necessary. That aligns better with the current [LLVM Debug Mode](https://libcxx.llvm.org/docs/DesignDocs/DebugMode.html) document as to how to enable debug mode. Specifically, the `std::__1::__libcpp_db::__insert_c(void*, std::__1::__c_node* (*)(void*, void*, std::__1::__c_node*))` symbol is undefined now if not more. – Louis Langholtz Aug 26 '20 at 19:13
  • Found a related stackoverflow question: https://stackoverflow.com/questions/15899937/is-it-possible-to-enable-libcpp-debug2-in-the-current-xcode-4-6-1-toolchain-on – Louis Langholtz Aug 26 '20 at 21:40

2 Answers2

2

According to the libc++ documentation:

Debug mode is currently not functional. Defining _LIBCPP_DEBUG will result in fairly nasty compile errors.

So that is probably the source of that.

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
  • The link to http://libcxx.llvm.org/debug_mode.html doesn't appear to work anymore. Seems like the documentation most relevant now is available at https://libcxx.llvm.org/docs/DesignDocs/DebugMode.html and is currently for libc++ 12.0. That page doesn't mention debug mode not being functional. Unfortunately, XCode seems to lag behind LLVM and debug mode in XCode 11.1 still doesn't appear to be usable. – Louis Langholtz Aug 25 '20 at 17:31
2

Baum mit Augen's answer that _LIBCPP_DEBUG_LEVEL >= 2 standard library code for lower level iterator debugging is basically unusable, appears to still be the case with the out-of-the-box Xcode 11.6. But if you're up for extra work or just want more specifics, read on...

Enabling _LIBCPP_DEBUG_LEVEL code is enabling LLVM's Debug Mode. According to that documentation, enabling this debug mode is done by defining the _LIBCPP_DEBUG to a value of 0 (that "enables most of libc++’s assertions") or 1 (that "enables 'iterator debugging' which provides additional assertions about the validity of iterators used by the program").

In XCode 11.6, I've found that adding _LIBCPP_DEBUG=0 to a project's Debug Preprocessor Macros setting, compiles and links and indeed adds additional checks - at least checking against out of range references to std::vector elements via its [] operator. Enabling the _LIBCPP_DEBUG_LEVEL >= 2 code is done by instead setting _LIBCPP_DEBUG=1. That alone however won't fully link as not all the necessary symbols are found. Specifically, the std::__1::__libcpp_db::__insert_c(void*, std::__1::__c_node* (*)(void*, void*, std::__1::__c_node*)) symbol is reported as undefined and maybe others as well. Presumably, XCode 11.6 did not ship with this built into the standard C++ library it provides. If anybody knows better or could corroborate this, I'd appreciate hearing from them.

With the following extra work, I've been able to enable libc++'s assertions plus the additional iterator debugging capabilities:

  1. Install a recent LLVM package somewhere that doesn't interfere with Xcode's included LLVM package. I installed LLVM 10.0.1 using Homebrew and I was able to access it then under /usr/local/Cellar/llvm/10.0.1.
  2. Have Xcode recognize the Xcode tool chain support that this new LLVM package provides. I added a symbolic link to /usr/local/Cellar/llvm/10.0.1/Toolchains/LLVM10.0.1.xctoolchain into Xcode's /Applications/Xcode.app/Contents/Developer/Toolchains directory. I'd done that while Xcode was running and it immediately saw the new tool chain but I had to restart Xcode to get it to compile with it.
  3. Under Xcode's "Xcode" -> "Toolchains" submenu, select the new tool chain. My setup showed "Xcode 11.7" and "org.llvm.10.0.1" and I selected the latter to accomplish this.
  4. Add the path to the new tool chain's usr/lib directory to the LIBRARY_SEARCH_PATHS declaration for resulting executable Targets. I did this by adding /usr/local/Cellar/llvm/10.0.1/Toolchains/LLVM10.0.1.xctoolchain/usr/lib to a project's executable target "Library Search Paths" "Debug" setting.
  5. Have the path to the new tool chain's include directory override the normal standard library's include directory. I haven't confirmed that this is necessary but did this by adding to my library and executable targets' OTHER_CPLUSPLUSFLAGS declaration the value of -nostdinc++ -I/usr/local/Cellar/llvm/10.0.1/Toolchains/LLVM10.0.1.xctoolchain/usr/include/c++/v1. From within Xcode, I'd achieved that by setting the "Other C++ Flags" setting to include this value for the targets of interest. I suspect it's probably safer to make this change at the project level than target level.
  6. Set the COMPILER_INDEX_STORE_ENABLE declaration to NO. This prevented "Unknown argument: '-index-store-path'" errors that stopped builds right from the beginning. I used Xcode's "Enable Index-While-Building Functionality" setting and set it to "No" for this.
  7. Add _LIBCPP_DEBUG=1 to the GCC_PREPROCESSOR_DEFINITIONS declaration for the project. Did this by adding it to Xcode's "Preprocessor Macros" "Debug" setting.

For related Q&A about this, see Is it possible to enable _LIBCPP_DEBUG2 in the current Xcode 4.6.1 toolchain on Mountain Lion?.

Louis Langholtz
  • 2,913
  • 3
  • 17
  • 40