Hi,
I’m working on an out of tree llvm pass.
For unit testing, it is convenient to create llvm::Instruction*
s manually, i.e. create an LLVMContext
, IRBuilder
, ScalarEvolution
, etc, and then build a proxy instruction sequence I’m trying to analyze.
Unfortunately, this triggers the LeakSanitizer:
==30325==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 72 byte(s) in 3 object(s) allocated from:
#0 0x7fc664abb1a8 in operator new(unsigned long) (/lib64/libasan.so.8+0xbb1a8)
#1 0x7fc65ec18455 in llvm::StringMapEntry<llvm::Value*>* llvm::StringMapEntry<llvm::Value*>::Create<llvm::MallocAllocator>(llvm::StringRef, llvm::MallocAllocator&) /usr/src/debug/llvm-15.0.6-1.fc37.x86_64/lib/Support/MemAlloc.cpp:16
#2 0x7ffef1971b4f ([stack]+0x1ab4f)
Direct leak of 48 byte(s) in 2 object(s) allocated from:
#0 0x7fc664abb1a8 in operator new(unsigned long) (/lib64/libasan.so.8+0xbb1a8)
#1 0x7fc65ec18455 in llvm::StringMapEntry<llvm::Value*>* llvm::StringMapEntry<llvm::Value*>::Create<llvm::MallocAllocator>(llvm::StringRef, llvm::MallocAllocator&) /usr/src/debug/llvm-15.0.6-1.fc37.x86_64/lib/Support/MemAlloc.cpp:16
#2 0x62580a in decltype(auto) llvm::dyn_cast<llvm::SCEVUnknown, llvm::SCEV const>(llvm::SCEV const*) /usr/include/llvm/Support/Casting.h:608
Direct leak of 24 byte(s) in 1 object(s) allocated from:
#0 0x7fc664abb1a8 in operator new(unsigned long) (/lib64/libasan.so.8+0xbb1a8)
#1 0x7fc65ec18455 in llvm::StringMapEntry<llvm::Value*>* llvm::StringMapEntry<llvm::Value*>::Create<llvm::MallocAllocator>(llvm::StringRef, llvm::MallocAllocator&) /usr/src/debug/llvm-15.0.6-1.fc37.x86_64/lib/Support/MemAlloc.cpp:16
Direct leak of 24 byte(s) in 1 object(s) allocated from:
#0 0x7fc664abb1a8 in operator new(unsigned long) (/lib64/libasan.so.8+0xbb1a8)
#1 0x7fc65ec18455 in llvm::StringMapEntry<llvm::Value*>* llvm::StringMapEntry<llvm::Value*>::Create<llvm::MallocAllocator>(llvm::StringRef, llvm::MallocAllocator&) /usr/src/debug/llvm-15.0.6-1.fc37.x86_64/lib/Support/MemAlloc.cpp:16
#2 0x7ffef1971cbf ([stack]+0x1acbf)
Indirect leak of 672 byte(s) in 7 object(s) allocated from:
#0 0x7fc664abb1a8 in operator new(unsigned long) (/lib64/libasan.so.8+0xbb1a8)
#1 0x7fc65ec16bb9 in llvm::User::operator new(unsigned long, unsigned int) (/lib64/libLLVM-15.so+0xe16bb9)
SUMMARY: AddressSanitizer: 840 byte(s) leaked in 14 allocation(s).
or
Indirect leak of 96 byte(s) in 1 object(s) allocated from:
#0 0x7fe385ebb1a8 in operator new(unsigned long) (/lib64/libasan.so.8+0xbb1a8)
#1 0x7fe37ffa1b39 in llvm::CastInst::Create(llvm::Instruction::CastOps, llvm::Value*, llvm::Type*, llvm::Twine const&, llvm::Instruction*) (/lib64/libLLVM-15.so+0xda1b39)
#2 0x624f2d in llvm::IRBuilderBase::CreateUIToFP(llvm::Value*, llvm::Type*, llvm::Twine const&) /usr/include/llvm/IR/IRBuilder.h:1916
#3 0x627247 in TestLoopFunction::CreateUIToF64(llvm::Value*) /home/chriselrod/Documents/progwork/cxx/LoopModels/test/./TestUtilities.hpp:133
#4 0x56f2c4 in MeanStDevTest0_BasicAssertions_Test::TestBody() /home/chriselrod/Documents/progwork/cxx/LoopModels/test/dependence_test.cpp:962
#5 0x8f8816 in void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /home/chriselrod/.cache/CPM/googletest/a36d6fcbd7356d396ea479e6b11f4b9760ad0c04/googletest/src/gtest.cc:2599
#6 0x8d6bbd in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /home/chriselrod/.cache/CPM/googletest/a36d6fcbd7356d396ea479e6b11f4b9760ad0c04/googletest/src/gtest.cc:2635
#7 0x83596f in testing::Test::Run() /home/chriselrod/.cache/CPM/googletest/a36d6fcbd7356d396ea479e6b11f4b9760ad0c04/googletest/src/gtest.cc:2674
#8 0x83929a in testing::TestInfo::Run() /home/chriselrod/.cache/CPM/googletest/a36d6fcbd7356d396ea479e6b11f4b9760ad0c04/googletest/src/gtest.cc:2853
#9 0x83d3d7 in testing::TestSuite::Run() /home/chriselrod/.cache/CPM/googletest/a36d6fcbd7356d396ea479e6b11f4b9760ad0c04/googletest/src/gtest.cc:3012
#10 0x8814df in testing::internal::UnitTestImpl::RunAllTests() /home/chriselrod/.cache/CPM/googletest/a36d6fcbd7356d396ea479e6b11f4b9760ad0c04/googletest/src/gtest.cc:5870
#11 0x8fd54e in bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /home/chriselrod/.cache/CPM/googletest/a36d6fcbd7356d396ea479e6b11f4b9760ad0c04/googletest/src/gtest.cc:2599
#12 0x8dbc22 in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /home/chriselrod/.cache/CPM/googletest/a36d6fcbd7356d396ea479e6b11f4b9760ad0c04/googletest/src/gtest.cc:2635
#13 0x875857 in testing::UnitTest::Run() /home/chriselrod/.cache/CPM/googletest/a36d6fcbd7356d396ea479e6b11f4b9760ad0c04/googletest/src/gtest.cc:5444
#14 0x7ea5ce in RUN_ALL_TESTS() /home/chriselrod/.cache/CPM/googletest/a36d6fcbd7356d396ea479e6b11f4b9760ad0c04/googletest/include/gtest/gtest.h:2293
#15 0x7ea3fd in main /home/chriselrod/.cache/CPM/googletest/a36d6fcbd7356d396ea479e6b11f4b9760ad0c04/googletest/src/gtest_main.cc:51
#16 0x7fe37e44a50f in __libc_start_call_main (/lib64/libc.so.6+0x2750f)
SUMMARY: AddressSanitizer: 305544 byte(s) leaked in 267 allocation(s).
(there were many more stack traces omitted above)
I don’t really see any documentation e.g. here on how to actually clean up the memory and avoid leaks.
Iterating over a set of llvm:Value*
s and calling deleteValue() accesses invalid memory.
Perhaps deleteValue
deletes some set of reachable values, and thus I need to call deleteValue()
on only a few?
Create[InstructionName]
and SCEVUnknown
show up in a lot of the stacktraces (e.g. the above two examples), so I imagine I need to do something there.
I assume these leaks are because I’m not calling clean up functions that do get called?
Or maybe this is an xy problem, and there is a better way to set up running unit tests on LLVM IR?