Command line options leaking

I’m experiencing an annoying fact using valgrind.
My software is linking against the support library and I get tons of leaks (at program termination, so not real leaks) regarding the command line options, even though I’m not using them.

==1033999== 47 bytes in 1 blocks are still reachable in loss record 438 of 947
==1033999==    at 0x483BE63: operator new(unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==1033999==    by 0x63349C8: llvm::allocate_buffer(unsigned long, unsigned long) (llvm/lib/Support/MemAlloc.cpp:15)
==1033999==    by 0x628D860: llvm::MallocAllocator::Allocate(unsigned long, unsigned long) (llvm/include/llvm/Support/AllocatorBase.h:85)
==1033999==    by 0x628D75B: void* llvm::StringMapEntryBase::allocateWithKey<llvm::MallocAllocator>(unsigned long, unsigned long, llvm::StringRef, llvm::MallocAllocator&) (llvm/include/llvm/ADT/StringMapEntry.h:50)
// cut for brevity
==1033999==    by 0x62746E1: (anonymous namespace)::CommandLineParser::addOption(llvm::cl::Option*, bool) (llvm/lib/Support/CommandLine.cpp:264)
==1033999==    by 0x6273DC0: llvm::cl::Option::addArgument() (llvm/lib/Support/CommandLine.cpp:448)
==1033999==    by 0x628A05E: llvm::cl::opt<bool, false, llvm::cl::parser<bool> >::done() (llvm/include/llvm/Support/CommandLine.h:1478)
==1033999==    by 0x7C8FABC: llvm::cl::opt<bool, false, llvm::cl::parser<bool> >::opt<char [31], llvm::cl::initializer<bool>, llvm::cl::desc>(char const (&) [31], llvm::cl::initializer<bool> const&, llvm::cl::desc const&) (llvm/include/llvm/Support/CommandLine.h:1502)
==1033999== 

My LLVM build has shared libraries enabled. I haven’t tried yet with static ones only, due to space and time constraints, but anyway I would like to stick the shared one.
From my understandings, command line options are defined all around llvm itself as global variables, and that is the reason why they are being initialized even though I don’t need the command line feature at all. Now the question is: can I avoid this somehow, apart from suppressing the warnings?
I suspect the answer to be negative, but I would like to point out the issue anyway. I’ve also seen some discussion about this same problem, but all I can find is something from a few years ago and thus I would apreciate a more up-to-date answer:
https://groups.google.com/g/llvm-dev/c/D4h_ZZzqcCU/m/W7oMfk9JP1oJ
https://bugs.llvm.org/show_bug.cgi?id=8860

From Valgrind’s doc:

  • “still reachable” means your program is probably ok – it didn’t free some memory it could have. This is quite common and often reasonable. Don’t use --show-reachable=yes if you don’t want to see these reports.

https://valgrind.org/docs/manual/faq.html#faq.deflost

Thank you. Yet the leaks also appears when I use the llvm’s command line features inside my tools. If I pass the parameter --help I get a lot of options that leak from the various llvm libraries. For now I’ve been defining my own categories and hiding the other ones with HideUnrelatedOptions, but I don’t feel this to be a good solution. Do you have any suggestion about this?

Ah right, that’s a different kind of leak :slight_smile:

It is fairly intrinsic to how cl::opt has been plumbed in LLVM, it is unfortunate but I also don’t see an easy fix.
The principle is that if you link a library in the application then you get the options to control the library available for “free”. This makes it easy to build and assemble debugging tools with minimal boilerplate, but that has its limit, as you noticed.
This is why MLIR is using explicit registration instead, it is a bit more boilerplate (you need to register dialects and passes explicitly for example), but you have better control of the end result.

Clear, thank you again :wink: