Skip to content

Commit 6e8f517

Browse files
committed
test/mon/test_election: free ConnectionTracker if blocked
in this test, if the connection is blocked, the allocated `ConnectionTracker` is leaked. as pointed out by ASan: ``` Indirect leak of 506880 byte(s) in 10560 object(s) allocated from: #0 0x563e9d9ea1ed in operator new(unsigned long) (/home/jenkins-build/build/workspace/ceph-pull-requests/build/bin/unittest_mon_election+0x2021ed) (BuildId: 6a9fb1b76c5d1db8d2bc9957316994f90b45b6c8) ceph#1 0x563e9da588a6 in __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<int const, double> > >::allocate(unsigned long, void const*) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/ext/new_allocator.h:127:27 ceph#2 0x563e9da58830 in std::allocator<std::_Rb_tree_node<std::pair<int const, double> > >::allocate(unsigned long) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/allocator.h:185:32 ceph#3 0x563e9da58830 in std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<int const, double> > > >::allocate(std::allocator<std::_Rb_tree_node<std::pair<int const, double> > >&, unsigned long) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/alloc_traits.h:464:20 ceph#4 0x563e9da58701 in std::_Rb_tree<int, std::pair<int const, double>, std::_Select1st<std::pair<int const, double> >, std::less<int>, std::allocator<std::pair<int const, double> > >::_M_get_node() /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_tree.h:561:16 ceph#5 0x563e9db6f424 in std::_Rb_tree_node<std::pair<int const, double> >* std::_Rb_tree<int, std::pair<int const, double>, std::_Select1st<std::pair<int const, double> >, std::less<int>, std::allocator<std::pair<int const, double> > >::_M_create_node<std::piecewise_construct_t const&, std::tuple<int const&>, std::tuple<> >(std::piecewise_construct_t const&, std::tuple<int const&>&&, std::tuple<>&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_tree.h:611:23 ceph#6 0x563e9db6efc0 in std::_Rb_tree_iterator<std::pair<int const, double> > std::_Rb_tree<int, std::pair<int const, double>, std::_Select1st<std::pair<int const, double> >, std::less<int>, std::allocator<std::pair<int const, double> > >::_M_emplace_hint_unique<std::piecewise_construct_t const&, std::tuple<int const&>, std::tuple<> >(std::_Rb_tree_const_iterator<std::pair<int const, double> >, std::piecewise_construct_t const&, std::tuple<int const&>&&, std::tuple<>&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_tree.h:2431:19 ceph#7 0x563e9db6ecb2 in std::map<int, double, std::less<int>, std::allocator<std::pair<int const, double> > >::operator[](int const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_map.h:501:15 ceph#8 0x563e9db6ca32 in std::enable_if<(!(denc_traits<int, void>::supported)) || (!(denc_traits<double, void>::supported)), void>::type ceph::decode<int, double, std::less<int>, std::allocator<std::pair<int const, double> >, denc_traits<int, void>, denc_traits<double, void> >(std::map<int, double, std::less<int>, std::allocator<std::pair<int const, double> > >&, ceph::buffer::v15_2_0::list::iterator_impl<true>&) /home/jenkins-build/build/workspace/ceph-pull-requests/src/include/encoding.h:1095:12 ceph#9 0x563e9db6c1d4 in ConnectionReport::decode(ceph::buffer::v15_2_0::list::iterator_impl<true>&) /home/jenkins-build/build/workspace/ceph-pull-requests/src/mon/ConnectionTracker.h:37:5 ceph#10 0x563e9db6ba3c in decode(ConnectionReport&, ceph::buffer::v15_2_0::list::iterator_impl<true>&) /home/jenkins-build/build/workspace/ceph-pull-requests/src/mon/ConnectionTracker.h:52:1 ceph#11 0x563e9db5a47e in std::enable_if<(!(denc_traits<int, void>::supported)) || (!(denc_traits<ConnectionReport, void>::supported)), void>::type ceph::decode<int, ConnectionReport, std::less<int>, std::allocator<std::pair<int const, ConnectionReport> >, denc_traits<int, void>, denc_traits<ConnectionReport, void> >(std::map<int, ConnectionReport, std::less<int>, std::allocator<std::pair<int const, ConnectionReport> > >&, ceph::buffer::v15_2_0::list::iterator_impl<true>&) /home/jenkins-build/build/workspace/ceph-pull-requests/src/include/encoding.h:1095:5 ceph#12 0x563e9db51b69 in ConnectionTracker::decode(ceph::buffer::v15_2_0::list::iterator_impl<true>&) /home/jenkins-build/build/workspace/ceph-pull-requests/src/mon/ConnectionTracker.cc:309:3 ceph#13 0x563e9da18bac in ConnectionTracker::ConnectionTracker(ceph::buffer::v15_2_0::list const&, ceph::common::CephContext*) /home/jenkins-build/build/workspace/ceph-pull-requests/src/mon/ConnectionTracker.h:180:5 ceph#14 0x563e9d9ef57f in Election::propose_to(int, int, unsigned int, ceph::buffer::v15_2_0::list&) /home/jenkins-build/build/workspace/ceph-pull-requests/src/test/mon/test_election.cc:369:15 ceph#15 0x563e9da22ccb in Owner::propose_to_peers(unsigned int, ceph::buffer::v15_2_0::list&) /home/jenkins-build/build/workspace/ceph-pull-requests/src/test/mon/test_election.cc:145:15 ceph#16 0x563e9db2da6c in ElectionLogic::start() /home/jenkins-build/build/workspace/ceph-pull-requests/src/mon/ElectionLogic.cc:143:12 ceph#17 0x563e9db2f128 in ElectionLogic::end_election_period() /home/jenkins-build/build/workspace/ceph-pull-requests/src/mon/ElectionLogic.cc:180:7 ceph#18 0x563e9da29a5d in Owner::election_timeout() /home/jenkins-build/build/workspace/ceph-pull-requests/src/test/mon/test_election.cc:242:11 ceph#19 0x563e9da19936 in Owner::notify_timestep() /home/jenkins-build/build/workspace/ceph-pull-requests/src/test/mon/test_election.cc:282:2 ceph#20 0x563e9d9f1181 in Election::run_timesteps(int) /home/jenkins-build/build/workspace/ceph-pull-requests/src/test/mon/test_election.cc:417:17 ``` in this change, we add an parameter to the handler function, so it can free the allocated `ConnectionTracker` instance. this should address the leakage reported by ASan. Signed-off-by: Kefu Chai <[email protected]>
1 parent 1602143 commit 6e8f517

File tree

1 file changed

+27
-14
lines changed

1 file changed

+27
-14
lines changed

src/test/mon/test_election.cc

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ struct Election {
7171
void queue_timeout_message(int from, int to, function<void()> m);
7272
void queue_stable_or_timeout(int from, int to,
7373
function<void()> m, function<void()> t);
74-
void queue_election_message(int from, int to, function<void()> m);
74+
void queue_election_message(int from, int to, function<void(bool)> m);
7575

7676
// test runner interfaces
7777
int run_timesteps(int max);
@@ -317,21 +317,24 @@ void Election::queue_stable_message(int from, int to, function<void()> m)
317317
}
318318
}
319319

320-
void Election::queue_election_message(int from, int to, function<void()> m)
320+
void Election::queue_election_message(int from, int to, function<void(bool)> m)
321321
{
322322
if (last_quorum_reported.count(from)) {
323323
last_quorum_change = timesteps_run;
324324
last_quorum_reported.clear();
325325
last_leader = -1;
326326
}
327-
if (!blocked_messages[from].count(to)) {
327+
const bool blocked = blocked_messages[from].count(to);
328+
if (blocked) {
329+
return m(true);
330+
} else {
328331
bufferlist bl;
329332
electors[from]->encode_scores(bl);
330333
Owner *o = electors[to];
331334
messages.push_back([this,m,o,bl] {
332335
--this->pending_election_messages;
333336
o->receive_scores(bl);
334-
m();
337+
m(false);
335338
});
336339
++pending_election_messages;
337340
}
@@ -356,37 +359,47 @@ void Election::queue_stable_or_timeout(int from, int to,
356359
void Election::defer_to(int from, int to, epoch_t e)
357360
{
358361
Owner *o = electors[to];
359-
queue_election_message(from, to, [o, from, e] {
360-
o->receive_ack(from, e);
361-
});
362+
queue_election_message(from, to, [o, from, e](bool blocked) {
363+
if (!blocked) {
364+
o->receive_ack(from, e);
365+
}
366+
});
362367
}
363368

364369
void Election::propose_to(int from, int to, epoch_t e, bufferlist& cbl)
365370
{
366371
Owner *o = electors[to];
367372
ConnectionTracker *oct = NULL;
368373
if (cbl.length()) {
369-
oct = new ConnectionTracker(cbl, g_ceph_context); // we leak these on blocked cons, meh
374+
oct = new ConnectionTracker(cbl, g_ceph_context);
370375
}
371-
queue_election_message(from, to, [o, from, e, oct] {
372-
o->receive_propose(from, e, oct);
376+
queue_election_message(from, to, [o, from, e, oct](bool blocked) {
377+
if (blocked) {
378+
delete oct;
379+
} else {
380+
o->receive_propose(from, e, oct);
381+
}
373382
});
374383
}
375384

376385
void Election::claim_victory(int from, int to, epoch_t e, const set<int>& members)
377386
{
378387
Owner *o = electors[to];
379-
queue_election_message(from, to, [o, from, e, members] {
388+
queue_election_message(from, to, [o, from, e, members](bool blocked) {
389+
if (!blocked) {
380390
o->receive_victory_claim(from, e, members);
381-
});
391+
}
392+
});
382393
}
383394

384395
void Election::accept_victory(int from, int to, epoch_t e)
385396
{
386397
Owner *o = electors[to];
387-
queue_election_message(from, to, [o, from, e] {
398+
queue_election_message(from, to, [o, from, e](bool blocked) {
399+
if (!blocked) {
388400
o->receive_victory_ack(from, e);
389-
});
401+
}
402+
});
390403
}
391404

392405
void Election::report_quorum(const set<int>& quorum)

0 commit comments

Comments
 (0)