1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2026-08-05 10:27:26 -04:00

deviceapi: Avoid iterator invalidation when clearing buddy lists

Fix cppcheck warning:
    Using iterator to member container 'm_sinkBuddies' that may be invalid

clearBuddiesLists() was iterating directly over m_sourceBuddies and
m_sinkBuddies while calling removeBuddy(), which modifies the buddy
relationship lists. This could invalidate the active iterator and result in
undefined behavior.

The issue could lead to intermittent failures during buddy cleanup operations,
such as device removal, device reload, or application shutdown, depending on
container state and timing.

Iterate over copies of the buddy lists so that removing relationships does not
affect the iterators used for traversal.

Signed-off-by: Robin Getz <rgetz503@gmail.com>
This commit is contained in:
Robin Getz
2026-08-01 17:06:39 -04:00
parent 11be1bb1e7
commit 0928de3b7b
+11 -8
View File
@@ -801,32 +801,35 @@ void DeviceAPI::removeBuddy(DeviceAPI* buddy)
void DeviceAPI::clearBuddiesLists()
{
auto itSource = m_sourceBuddies.begin();
auto itSink = m_sinkBuddies.begin();
// Make copies before iterating because removeBuddy() modifies the buddy
// relationship lists. Iterating directly over m_sourceBuddies/m_sinkBuddies
// could invalidate iterators while the relationships are being removed.
auto sourceCopy = m_sourceBuddies;
auto sinkCopy = m_sinkBuddies;
bool leaderElected = false;
for (;itSource != m_sourceBuddies.end(); ++itSource)
for (auto* buddy : sourceCopy)
{
if (isBuddyLeader() && !leaderElected)
{
(*itSource)->setBuddyLeader(true);
buddy->setBuddyLeader(true);
leaderElected = true;
}
(*itSource)->removeBuddy(this);
buddy->removeBuddy(this);
}
m_sourceBuddies.clear();
for (;itSink != m_sinkBuddies.end(); ++itSink)
for (auto* buddy : sinkCopy)
{
if (isBuddyLeader() && !leaderElected)
{
(*itSink)->setBuddyLeader(true);
buddy->setBuddyLeader(true);
leaderElected = true;
}
(*itSink)->removeBuddy(this);
buddy->removeBuddy(this);
}
m_sinkBuddies.clear();