Skip to content

Commit 7c5db3e

Browse files
committed
test/test_not_before_queue: Fix memory leak by freeing ineligible items in destructor
Fix memory leak in test_not_before_queue identified by AddressSanitizer. Previously, the test was terminating without properly dequeueing all elements, causing resource leaks during teardown. This change implements a proper cleanup mechanism that: 1. Advances the queue's time until all elements become eligible for processing 2. Dequeues all remaining elements to ensure proper destruction 3. Guarantees clean teardown even for elements with future timestamps The fix eliminates ASan-reported leaks occurring in the not_before_queue_t::enqueue method when test cases were torn down prematurely. A sample of the error from ASan: ``` Direct leak of 1800 byte(s) in 15 object(s) allocated from: #0 0x7f71b1f1ab5b in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:86 ceph#1 0x55fb4c977058 in void not_before_queue_t<tv_t, test_time_t>::enqueue<tv_t const&>(tv_t const&) /home/kefu/dev/ceph/src/common/not_before_queue.h:164 ceph#2 0x55fb4c97748b in NotBeforeTest::load_test_data(std::vector<tv_t, std::allocator<tv_t> > const&) /home/kefu/dev/ceph/src/test/test_not_before_queue.cc:67 ceph#3 0x55fb4c961112 in NotBeforeTest_RemoveIfByClass_no_cond_Test::TestBody() /home/kefu/dev/ceph/src/test/test_not_before_queue.cc:213 ceph#4 0x55fb4ca05f67 in void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /home/kefu/dev/ceph/src/googletest/googletest/src/gtest.cc:2653 ceph#5 0x55fb4ca1c4f7 in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /home/kefu/dev/ceph/src/googletest/googletest/src/gtest.cc:2689 ceph#6 0x55fb4c9e1104 in testing::Test::Run() /home/kefu/dev/ceph/src/googletest/googletest/src/gtest.cc:2728 ceph#7 0x55fb4c9e16e2 in testing::TestInfo::Run() /home/kefu/dev/ceph/src/googletest/googletest/src/gtest.cc:2874 ceph#8 0x55fb4c9e73b4 in testing::TestSuite::Run() /home/kefu/dev/ceph/src/googletest/googletest/src/gtest.cc:3052 ceph#9 0x55fb4c9f059b in testing::internal::UnitTestImpl::RunAllTests() /home/kefu/dev/ceph/src/googletest/googletest/src/gtest.cc:6004 ceph#10 0x55fb4ca064ff in bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /home/kefu/dev/ceph/src/googletest/googletest/src/gtest.cc:2653 ceph#11 0x55fb4ca1d1bf in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /home/kefu/dev/ceph/src/googletest/googletest/src/gtest.cc:2689 ceph#12 0x55fb4c9e124d in testing::UnitTest::Run() /home/kefu/dev/ceph/src/googletest/googletest/src/gtest.cc:5583 ceph#13 0x55fb4c97a0b6 in RUN_ALL_TESTS() /home/kefu/dev/ceph/src/googletest/googletest/include/gtest/gtest.h:2334 ceph#14 0x55fb4c979ffc in main /home/kefu/dev/ceph/src/googletest/googlemock/src/gmock_main.cc:71 ceph#15 0x7f71ae833ca7 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 SUMMARY: AddressSanitizer: 1800 byte(s) leaked in 15 allocation(s). ``` Signed-off-by: Kefu Chai <[email protected]>
1 parent b71625d commit 7c5db3e

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed

src/test/test_not_before_queue.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ class NotBeforeTest : public testing::Test {
6262
public:
6363
using queue_t = not_before_queue_t<tv_t, test_time_t>;
6464

65+
~NotBeforeTest() {
66+
// Advance time until all queued items become eligible for processing.
67+
// This ensures complete dequeuing during test teardown, preventing memory leaks.
68+
// We assume test cutoff timepoints remain within reasonable bounds. If a specified
69+
// timepoint precedes current time, the process continues advancing normally.
70+
for (unsigned when = 1; queue.eligible_count() < queue.total_count(); when += 1) {
71+
queue.advance_time(when);
72+
}
73+
while (queue.dequeue()) {}
74+
}
6575
void load_test_data(const std::vector<tv_t> &dt) {
6676
for (const auto &d : dt) {
6777
queue.enqueue(d);

0 commit comments

Comments
 (0)