Hi,
Hello all!
I find that using lldb to debug LLVM libraries can be super
frustrating, because a lot of LLVM classes, like the constructor for
StringRef, are marked LLVM_ATTRIBUTE_ALWAYS_INLINE. So when I attempt
to have lldb evaluate an expression that implicitly instantiates a
StringRef, I get 'error: Couldn't lookup symbols:
__ZN4llvm9StringRefC1EPKc'.
As an example, most recently this happened to me when playing around
with llvm::AttributeSet, having attached lldb to an opt built with
-DCMAKE_BUILD_TYPE="Debug":
(lldb) e $AS.hasAttribute("myattr")
error: Couldn't lookup symbols:
__ZN4llvm9StringRefC1EPKc
Despite having built in a "Debug" configuration,
LLVM_ATTRIBUTE_ALWAYS_INLINE makes it very difficult to debug LLVM.
How do you all deal with or work around this problem?
I don't think there are any great workarounds. The data formatters in utils/lldbDataFormatters.py can help a bit.
Is there a good
way to do so? If not, would anyone object if I sent up a patch to
introduce a CMake variable or something to conditionally disable
LLVM_ATTRIBUTE_ALWAYS_INLINE? I'd like to be able to turn it off, but
I'm not sure if there's some good reason it needs to stay on even for
debug builds?
IIRC the motivation for using always_inline in debug builds was to make binaries acceptably fast. IMHO this isn't the right tradeoff because it also makes binaries frustratingly hard to debug.
Some might object that with clang modules, it should be no trouble for a debugger to evaluate these kinds of expressions. I've CC'd Raphael who can speak to this much better than I can. My understanding is that modules may help, but lldb (and presumably gdb as well?) are not going to learn how to parse templated code out of C++ modules, instantiate them, and JIT-compile them for you really soon. That seems like an ongoing, longer-term project.
I'd like to see us move away from using always_inline in core ADT headers to make debugging easier in the near future.
A note about slow Debug binaries. In my experience it's really never necessary have a separate Debug build tree. It takes up a slot of time/space and I've never found it useful. It's usually much more convenient to have a single RelAsserts build tree. If you need to debug code in some .cpp file, you can just:
$ touch path/to/the/file.cpp
$ export CCC_OVERRIDE_OPTIONS="+-g O0 +-UNDEBUG"
$ ninja opt/clang/etc
The build system will do an incremental recompile of the binary you want to debug, with the *single file* (or set of files) you care about recompiled with asserts, at -O0, with debug info. The resulting binary is pretty much just as fast as a RelAsserts binary and is perfectly debuggable, modulo always_inline functions 
vedant