<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[shiboken6 6.11.1: SIGSEGV in QUndoStack::clear() — pushed QUndoCommand double-deleted when stack and command are cyclic garbage]]></title><description><![CDATA[<p dir="auto"><strong>Environment:</strong> PySide6 / shiboken6 6.11.1, CPython 3.14.5, Linux x86_64 (glibc 2.43)</p>
<p dir="auto"><strong>Summary:</strong> when a parentless <code>QUndoStack</code> created from Python (so the wrapper owns the C++ object) holds a pushed <code>QUndoCommand</code>, and both wrappers become unreachable in the same Python reference-cycle collection, <code>gc.collect()</code> segfaults inside <code>QUndoStack::clear()</code>. No <code>QApplication</code> and no Python subclassing required.</p>
<p dir="auto"><strong>Deterministic reproducer</strong> (crashes 10/10, exit 139):</p>
<pre><code class="language-python">import gc
from PySide6.QtGui import QUndoCommand, QUndoStack

cmd = QUndoCommand("cmd")   # command wrapper allocated BEFORE the stack wrapper
stack = QUndoStack()
stack.me = stack            # any cycle: the stack must die inside the GC pass
stack.push(cmd)             # shiboken parentship: stack owns command

del cmd, stack
gc.collect()                # SIGSEGV
</code></pre>
<p dir="auto"><strong>Mechanism</strong> (shiboken6 6.11.1, <code>sources/shiboken6/libshiboken/basewrapper.cpp</code>):</p>
<p dir="auto">When CPython's <code>delete_garbage()</code> tp_clears the <strong>command</strong> wrapper first, <code>SbkObject_tp_clear</code> (line 298) calls <code>Shiboken::Object::removeParent(child)</code> with the default arguments <code>giveOwnershipBack=true, keepReference=false</code> (line 1746), handing C++ ownership of the command back to Python. The follow-up DECREF frees the wrapper and <code>SbkDeallocWrapperCommon</code> runs <code>cpp_dtor</code>, deleting the C++ <code>QUndoCommand</code> while the C++ <code>QUndoStack::d-&gt;command_list</code> still holds the raw pointer (<code>push()</code> is an unconditional ownership transfer; there is no removal API). When the stack wrapper is torn down later in the same pass, <code>~QUndoStack()</code> → <code>clear()</code> → <code>qDeleteAll(d-&gt;command_list)</code> makes a virtual call through the freed command's clobbered vptr → SIGSEGV (faulting pc is <code>0x0</code> in gdb).</p>
<p dir="auto">The opposite tp_clear order is handled correctly (<code>_destroyParentInfo</code> invalidates children with <code>giveOwnershipBack=false</code>), which is why this presents as selection-dependent "flaky" crashes in real applications. We first hit it as intermittent pytest-teardown segfaults in a widgets app whose panels hold a parentless undo stack.</p>
<p dir="auto">Faulthandler C stack of the crash:</p>
<pre><code>libQt6Gui.so.6              QUndoStack::clear() + 0x142
libQt6Gui.so.6              QUndoStack::~QUndoStack() + 0x36
QtGui.abi3.so               (wrapper dealloc)
libshiboken6.abi3.so.6.11   SbkDeallocWrapperCommon
python                      _Py_Dealloc
python                      gc_collect_main   ("Garbage-collecting")
</code></pre>
<p dir="auto"><strong>Workarounds:</strong> parent the <code>QUndoStack</code> to a QObject, or explicitly <code>stack.clear()</code> while both halves are alive before dropping the last Python references.</p>
]]></description><link>https://forum.qt.io/topic/164878/shiboken6-6.11.1-sigsegv-in-qundostack-clear-pushed-qundocommand-double-deleted-when-stack-and-command-are-cyclic-garbage</link><generator>RSS for Node</generator><lastBuildDate>Sun, 19 Jul 2026 23:05:17 GMT</lastBuildDate><atom:link href="https://forum.qt.io/topic/164878.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 12 Jul 2026 09:21:09 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to shiboken6 6.11.1: SIGSEGV in QUndoStack::clear() — pushed QUndoCommand double-deleted when stack and command are cyclic garbage on Tue, 14 Jul 2026 12:54:36 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/demotu">@<bdi>demotu</bdi></a> Take a look at <a href="https://forum.qt.io/topic/164253/about-accessing-the-bug-report-system?_=1784033640203">https://forum.qt.io/topic/164253/about-accessing-the-bug-report-system?_=1784033640203</a></p>
]]></description><link>https://forum.qt.io/post/839152</link><guid isPermaLink="true">https://forum.qt.io/post/839152</guid><dc:creator><![CDATA[jsulm]]></dc:creator><pubDate>Tue, 14 Jul 2026 12:54:36 GMT</pubDate></item><item><title><![CDATA[Reply to shiboken6 6.11.1: SIGSEGV in QUndoStack::clear() — pushed QUndoCommand double-deleted when stack and command are cyclic garbage on Mon, 13 Jul 2026 03:49:58 GMT]]></title><description><![CDATA[<p dir="auto">Yes, I would normally file this on Jira, but my account currently can't create issues. Posting here so it doesn't stall — if a maintainer wants to file it, please do.</p>
]]></description><link>https://forum.qt.io/post/839126</link><guid isPermaLink="true">https://forum.qt.io/post/839126</guid><dc:creator><![CDATA[demotu]]></dc:creator><pubDate>Mon, 13 Jul 2026 03:49:58 GMT</pubDate></item><item><title><![CDATA[Reply to shiboken6 6.11.1: SIGSEGV in QUndoStack::clear() — pushed QUndoCommand double-deleted when stack and command are cyclic garbage on Sun, 12 Jul 2026 10:33:48 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/demotu">@<bdi>demotu</bdi></a><br />
Since this is a user forum, you should report this at <a href="https://qt-project.atlassian.net/jira/software/c/projects/PYSIDE/list" target="_blank" rel="noopener noreferrer nofollow ugc">https://qt-project.atlassian.net/jira/software/c/projects/PYSIDE/list</a>.</p>
]]></description><link>https://forum.qt.io/post/839116</link><guid isPermaLink="true">https://forum.qt.io/post/839116</guid><dc:creator><![CDATA[JonB]]></dc:creator><pubDate>Sun, 12 Jul 2026 10:33:48 GMT</pubDate></item></channel></rss>