Skip to content

Commit 5a9a620

Browse files
committed
Fix crash on quit after removing a source (double-free)
MappingManager::removeSource() explicitly called source->~Source(). Because the destructor is virtual, that ran the full destructor chain on an object still owned by QSharedPointer (e.g. retained by the undo stack for undo), so the object was destroyed a second time when the last shared pointer was released — a double-free that crashed in ~QObject() on quit (and on undo). It was most visible with Syphon sources, which carry extra state (an Objective-C client and a queued signal connection), but the bug applied to any removed source. Drop the explicit destructor call and let QSharedPointer own the lifetime; removing the manager's references is enough.
1 parent 29869fb commit 5a9a620

1 file changed

Lines changed: 10 additions & 2 deletions

File tree

src/core/MappingManager.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,20 @@ bool MappingManager::removeSource(uid sourceId)
119119
removeLayer(it.key());
120120
}
121121

122-
// Remove source.
122+
// Remove source. Its lifetime is managed by QSharedPointer: dropping the
123+
// manager's references here is enough. The source may still be held by the
124+
// undo stack (so it can be restored), and is freed once the last shared
125+
// pointer is released.
126+
//
127+
// NOTE: do NOT call source->~Source() explicitly. Because ~Source() is
128+
// virtual, that runs the full destructor chain on an object the shared
129+
// pointers still own, so the object is destroyed a second time when the
130+
// last reference is released — a double-free that crashes on quit/undo
131+
// (notably with Syphon sources, which carry extra state).
123132
int idx = sourceVector.lastIndexOf(source);
124133
Q_ASSERT(idx != -1);
125134
sourceVector.remove(idx);
126135
sourceMap.remove(sourceId);
127-
source->~Source(); // FIX ME: Explicit call of source destructor in order add Camera more than once
128136
return true;
129137
}
130138
else

0 commit comments

Comments
 (0)