<table><tr><td style="">alnikiforov added a comment.
</td><a style="text-decoration: none; padding: 4px 8px; margin: 0 8px 8px; float: right; color: #464C5C; font-weight: bold; border-radius: 3px; background-color: #F7F7F9; background-image: linear-gradient(to bottom,#fff,#f1f0f1); display: inline-block; border: 1px solid rgba(71,87,120,.2);" href="https://phabricator.kde.org/D27650">View Revision</a></tr></table><br /><div><div><blockquote style="border-left: 3px solid #8C98B8;
color: #6B748C;
font-style: italic;
margin: 4px 0 12px 0;
padding: 8px 12px;
background-color: #F8F9FC;">
<div style="font-style: normal;
padding-bottom: 4px;">In <a href="https://phabricator.kde.org/D27650#617550" style="background-color: #e7e7e7;
border-color: #e7e7e7;
border-radius: 3px;
padding: 0 4px;
font-weight: bold;
color: black;text-decoration: none;">D27650#617550</a>, <a href="https://phabricator.kde.org/p/davidedmundson/" style="
border-color: #f1f7ff;
color: #19558d;
background-color: #f1f7ff;
border: 1px solid transparent;
border-radius: 3px;
font-weight: bold;
padding: 0 4px;">@davidedmundson</a> wrote:</div>
<div style="margin: 0;
padding: 0;
border: 0;
color: rgb(107, 116, 140);"><blockquote style="border-left: 3px solid #a7b5bf; color: #464c5c; font-style: italic; margin: 4px 0 12px 0; padding: 4px 12px; background-color: #f8f9fc;"><p>This function takes a plain pointer and wraps it into weak shared pointer.</p></blockquote>
<p>That's QWeakPointer.</p>
<p>QPointer is something else that doesn't have an equivalent in stdlib.<br />
It takes a QObject, then QObject has a special hook to unset watching QPointers to nullptr in QObject::~QObject()</p></div>
</blockquote>
<p>QPointer actually uses QWeakPointer to work:</p>
<p><a href="https://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/kernel/qpointer.h#n59" class="remarkup-link" target="_blank" rel="noreferrer">https://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/kernel/qpointer.h#n59</a><br />
<a href="https://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/tools/qsharedpointer_impl.h#n309" class="remarkup-link" target="_blank" rel="noreferrer">https://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/tools/qsharedpointer_impl.h#n309</a><br />
<a href="https://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/tools/qsharedpointer_impl.h#n450" class="remarkup-link" target="_blank" rel="noreferrer">https://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/tools/qsharedpointer_impl.h#n450</a><br />
<a href="https://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/tools/qsharedpointer_impl.h#n569" class="remarkup-link" target="_blank" rel="noreferrer">https://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/tools/qsharedpointer_impl.h#n569</a></p>
<p>And this used QWeakPointer leads to premature destruction of object m_layout points to.</p>
<blockquote style="border-left: 3px solid #a7b5bf; color: #464c5c; font-style: italic; margin: 4px 0 12px 0; padding: 4px 12px; background-color: #f8f9fc;"><p>I don't understand how this could fix anything.</p>
<p>If this is null before, then after this patch m_layout would just be dangling which is worse.</p></blockquote>
<p>I've debugged this issue a bit more. Here's what I found.</p>
<p>Initial setup from gdb:</p>
<div class="remarkup-code-block" style="margin: 12px 0;" data-code-lang="text" data-sigil="remarkup-code-block"><pre class="remarkup-code" style="font: 11px/15px "Menlo", "Consolas", "Monaco", monospace; padding: 12px; margin: 0; background: rgba(71, 87, 120, 0.08);">(gdb) break ItemContainer::setLayout
Breakpoint 1 at 0x7fffba5e2ea0: file /usr/src/debug/plasma-workspace-5.18.1/components/containmentlayoutmanager/itemcontainer.cpp, line 177.
(gdb) run --replace
Thread 1 "plasmashell" hit Breakpoint 1, ItemContainer::setLayout (this=this@entry=0xc01f80, layout=0x0) at /usr/src/debug/plasma-workspace-5.18.1/components/containmentlayoutmanager/itemcontainer.cpp:177
177 {
(gdb) c
Continuing.
Thread 1 "plasmashell" hit Breakpoint 1, ItemContainer::setLayout (this=0xc01f80, layout=0xbe0a60) at /usr/src/debug/plasma-workspace-5.18.1/components/containmentlayoutmanager/itemcontainer.cpp:177
177 {
(gdb) n
178 if (m_layout == layout) {
(gdb) n
198 if (parentItem() != layout) {
(gdb) n
210 });
(gdb) print m_layout
$1 = {wp = {d = 0xc01bc0, value = 0xbe0a60}}
(gdb) print m_layout.wp.d
$2 = (QWeakPointer<QObject>::Data *) 0xc01bc0
(gdb) print *m_layout.wp.d
$3 = {weakref = {_q_value = {<std::__atomic_base<int>> = {static _S_alignment = 4, _M_i = 4}, <No data fields>}}, strongref = {_q_value = {<std::__atomic_base<int>> = {static _S_alignment = 4, _M_i = -1}, <No data fields>}},
destroyer = 0x7ffff57ada40 <main_arena+96>}
(gdb) watch ((QWeakPointer<QObject>::Data *) 0xc01bc0)->weakref._q_value._M_i
Hardware watchpoint 2: ((QWeakPointer<QObject>::Data *) 0xc01bc0)->weakref._q_value._M_i
(gdb) watch ((QWeakPointer<QObject>::Data *) 0xc01bc0)->strongref._q_value._M_i
Hardware watchpoint 3: ((QWeakPointer<QObject>::Data *) 0xc01bc0)->strongref._q_value._M_i
(gdb) break QObject::~QObject if (this == 0xbe0a60)
Breakpoint 4 at 0x41c3e0 (75 locations)
(gdb) c
Continuing.</pre></div>
<p>I've added some widgets like described in test plan. Now I'm removing one of widgets:</p>
<div class="remarkup-code-block" style="margin: 12px 0;" data-code-lang="text" data-sigil="remarkup-code-block"><pre class="remarkup-code" style="font: 11px/15px "Menlo", "Consolas", "Monaco", monospace; padding: 12px; margin: 0; background: rgba(71, 87, 120, 0.08);">Thread 1 "plasmashell" hit Hardware watchpoint 2: ((QWeakPointer<QObject>::Data *) 0xc01bc0)->weakref._q_value._M_i
Old value = 5
New value = 4
0x00007fffba5e4445 in QWeakPointer<QObject>::~QWeakPointer (this=0x10c2fc0, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/atomic_base.h:326
326 operator--() noexcept
(gdb) bt
#0 0x00007fffba5e4445 in QWeakPointer<QObject>::~QWeakPointer (this=0x10c2fc0, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/atomic_base.h:326
#1 QPointer<AppletsLayout>::~QPointer (this=0x10c2fc0, __in_chrg=<optimized out>) at /usr/include/qt5/QtCore/qpointer.h:53
#2 ItemContainer::~ItemContainer (this=0x10c2f60, __in_chrg=<optimized out>) at /usr/src/debug/plasma-workspace-5.18.1/components/containmentlayoutmanager/itemcontainer.cpp:64
#3 0x00007fffba5d30a5 in QQmlPrivate::QQmlElement<AppletContainer>::~QQmlElement (this=0x10c2f60, __in_chrg=<optimized out>) at /usr/include/qt5/QtQml/qqmlprivate.h:106
#4 QQmlPrivate::QQmlElement<AppletContainer>::~QQmlElement (this=0x10c2f60, __in_chrg=<optimized out>) at /usr/include/qt5/QtQml/qqmlprivate.h:108
#5 0x00007ffff5ce2380 in QObject::event (this=this@entry=0x10c2f60, e=e@entry=0x2b76cc0) at kernel/qobject.cpp:1252
#6 0x00007ffff77c2ae3 in QQuickItem::event (this=0x10c2f60, ev=0x2b76cc0) at items/qquickitem.cpp:8105
#7 0x00007ffff6711c42 in QApplicationPrivate::notify_helper (this=this@entry=0x4c14c0, receiver=receiver@entry=0x10c2f60, e=e@entry=0x2b76cc0) at kernel/qapplication.cpp:3700
#8 0x00007ffff671b1c0 in QApplication::notify (this=0x7fffffffd730, receiver=0x10c2f60, e=0x2b76cc0) at kernel/qapplication.cpp:3446
#9 0x00007ffff5cb7212 in QCoreApplication::notifyInternal2 (receiver=0x10c2f60, event=0x2b76cc0) at ../../src/corelib/kernel/qobject.h:142
#10 0x00007ffff5cb9e08 in QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x4b6330) at kernel/qcoreapplication.cpp:1825
#11 0x00007ffff5d0d963 in postEventSourceDispatch (s=0x51a7c0) at kernel/qeventdispatcher_glib.cpp:276
#12 0x00007ffff3b86c6d in g_main_dispatch (context=0x7fffe8005010) at ../glib/gmain.c:3179
#13 g_main_context_dispatch (context=context@entry=0x7fffe8005010) at ../glib/gmain.c:3844
#14 0x00007ffff3b86ef0 in g_main_context_iterate (context=context@entry=0x7fffe8005010, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/gmain.c:3917
#15 0x00007ffff3b86f7f in g_main_context_iteration (context=0x7fffe8005010, may_block=may_block@entry=1) at ../glib/gmain.c:3978
#16 0x00007ffff5d0cfa1 in QEventDispatcherGlib::processEvents (this=0x51b110, flags=...) at kernel/qeventdispatcher_glib.cpp:422
#17 0x00007ffff5cb5e9b in QEventLoop::exec (this=this@entry=0x7fffffffd5f0, flags=..., flags@entry=...) at ../../src/corelib/global/qflags.h:140
#18 0x00007ffff5cbd942 in QCoreApplication::exec () at ../../src/corelib/global/qflags.h:120
#19 0x00007ffff608ecbc in QGuiApplication::exec () at kernel/qguiapplication.cpp:1784
#20 0x00007ffff6711bb5 in QApplication::exec () at kernel/qapplication.cpp:2856
#21 0x000000000041f4f1 in main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/plasma-workspace-5.18.1/shell/main.cpp:228
(gdb) c
Continuing.
Thread 1 "plasmashell" hit Breakpoint 1, ItemContainer::setLayout (this=0x10c2f60, layout=0x0) at /usr/src/debug/plasma-workspace-5.18.1/components/containmentlayoutmanager/itemcontainer.cpp:177
177 {
(gdb) bt
#0 ItemContainer::setLayout (this=0x10c2f60, layout=0x0) at /usr/src/debug/plasma-workspace-5.18.1/components/containmentlayoutmanager/itemcontainer.cpp:177
#1 0x00007ffff5ce1c98 in QtPrivate::QSlotObjectBase::call (a=0x7fffffffcee0, r=0x10c2f60, this=0x2dcf4b0) at ../../src/corelib/kernel/qobjectdefs_impl.h:394
#2 QMetaObject::activate (sender=0x10c2f60, signalOffset=<optimized out>, local_signal_index=<optimized out>, argv=<optimized out>) at kernel/qobject.cpp:3784
#3 0x00007ffff77aedb2 in QQuickItem::parentChanged (this=this@entry=0x10c2f60, _t1=<optimized out>) at .moc/moc_qquickitem.cpp:1100
#4 0x00007ffff77c3fdd in QQuickItem::setParentItem (this=this@entry=0x10c2f60, parentItem=parentItem@entry=0x0) at items/qquickitem.cpp:2808
#5 0x00007ffff77c4c38 in QQuickItem::~QQuickItem (this=0x10c2f60, __in_chrg=<optimized out>) at items/qquickitem.cpp:2390
#6 0x00007fffba5d30a5 in QQmlPrivate::QQmlElement<AppletContainer>::~QQmlElement (this=0x10c2f60, __in_chrg=<optimized out>) at /usr/include/qt5/QtQml/qqmlprivate.h:106
#7 QQmlPrivate::QQmlElement<AppletContainer>::~QQmlElement (this=0x10c2f60, __in_chrg=<optimized out>) at /usr/include/qt5/QtQml/qqmlprivate.h:108
#8 0x00007ffff5ce2380 in QObject::event (this=this@entry=0x10c2f60, e=e@entry=0x2b76cc0) at kernel/qobject.cpp:1252
#9 0x00007ffff77c2ae3 in QQuickItem::event (this=0x10c2f60, ev=0x2b76cc0) at items/qquickitem.cpp:8105
#10 0x00007ffff6711c42 in QApplicationPrivate::notify_helper (this=this@entry=0x4c14c0, receiver=receiver@entry=0x10c2f60, e=e@entry=0x2b76cc0) at kernel/qapplication.cpp:3700
#11 0x00007ffff671b1c0 in QApplication::notify (this=0x7fffffffd730, receiver=0x10c2f60, e=0x2b76cc0) at kernel/qapplication.cpp:3446
#12 0x00007ffff5cb7212 in QCoreApplication::notifyInternal2 (receiver=0x10c2f60, event=0x2b76cc0) at ../../src/corelib/kernel/qobject.h:142
#13 0x00007ffff5cb9e08 in QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x4b6330) at kernel/qcoreapplication.cpp:1825
#14 0x00007ffff5d0d963 in postEventSourceDispatch (s=0x51a7c0) at kernel/qeventdispatcher_glib.cpp:276
#15 0x00007ffff3b86c6d in g_main_dispatch (context=0x7fffe8005010) at ../glib/gmain.c:3179
#16 g_main_context_dispatch (context=context@entry=0x7fffe8005010) at ../glib/gmain.c:3844
#17 0x00007ffff3b86ef0 in g_main_context_iterate (context=context@entry=0x7fffe8005010, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/gmain.c:3917
#18 0x00007ffff3b86f7f in g_main_context_iteration (context=0x7fffe8005010, may_block=may_block@entry=1) at ../glib/gmain.c:3978
#19 0x00007ffff5d0cfa1 in QEventDispatcherGlib::processEvents (this=0x51b110, flags=...) at kernel/qeventdispatcher_glib.cpp:422
#20 0x00007ffff5cb5e9b in QEventLoop::exec (this=this@entry=0x7fffffffd5f0, flags=..., flags@entry=...) at ../../src/corelib/global/qflags.h:140
#21 0x00007ffff5cbd942 in QCoreApplication::exec () at ../../src/corelib/global/qflags.h:120
#22 0x00007ffff608ecbc in QGuiApplication::exec () at kernel/qguiapplication.cpp:1784
#23 0x00007ffff6711bb5 in QApplication::exec () at kernel/qapplication.cpp:2856
#24 0x000000000041f4f1 in main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/plasma-workspace-5.18.1/shell/main.cpp:228
(gdb) c
Continuing.
Thread 1 "plasmashell" hit Hardware watchpoint 2: ((QWeakPointer<QObject>::Data *) 0xc01bc0)->weakref._q_value._M_i
Old value = 4
New value = 3
0x00007fffba5e2fd7 in QWeakPointer<QObject>::~QWeakPointer (this=<synthetic pointer>, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/atomic_base.h:326
326 operator--() noexcept
(gdb) bt
#0 0x00007fffba5e2fd7 in QWeakPointer<QObject>::~QWeakPointer (this=<synthetic pointer>, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/atomic_base.h:326
#1 QWeakPointer<QObject>::operator= (other=..., other=..., this=0x10c2fc0) at /usr/include/qt5/QtCore/qsharedpointer_impl.h:599
#2 QWeakPointer<QObject>::assign<QObject> (ptr=0x0, this=0x10c2fc0) at /usr/include/qt5/QtCore/qsharedpointer_impl.h:684
#3 QPointer<AppletsLayout>::operator= (p=0x0, this=0x10c2fc0) at /usr/include/qt5/QtCore/qpointer.h:83
#4 ItemContainer::setLayout (this=0x10c2f60, layout=0x0) at /usr/src/debug/plasma-workspace-5.18.1/components/containmentlayoutmanager/itemcontainer.cpp:191
#5 0x00007ffff5ce1c98 in QtPrivate::QSlotObjectBase::call (a=0x7fffffffcee0, r=0x10c2f60, this=0x2dcf4b0) at ../../src/corelib/kernel/qobjectdefs_impl.h:394
#6 QMetaObject::activate (sender=0x10c2f60, signalOffset=<optimized out>, local_signal_index=<optimized out>, argv=<optimized out>) at kernel/qobject.cpp:3784
#7 0x00007ffff77aedb2 in QQuickItem::parentChanged (this=this@entry=0x10c2f60, _t1=<optimized out>) at .moc/moc_qquickitem.cpp:1100
#8 0x00007ffff77c3fdd in QQuickItem::setParentItem (this=this@entry=0x10c2f60, parentItem=parentItem@entry=0x0) at items/qquickitem.cpp:2808
#9 0x00007ffff77c4c38 in QQuickItem::~QQuickItem (this=0x10c2f60, __in_chrg=<optimized out>) at items/qquickitem.cpp:2390
#10 0x00007fffba5d30a5 in QQmlPrivate::QQmlElement<AppletContainer>::~QQmlElement (this=0x10c2f60, __in_chrg=<optimized out>) at /usr/include/qt5/QtQml/qqmlprivate.h:106
#11 QQmlPrivate::QQmlElement<AppletContainer>::~QQmlElement (this=0x10c2f60, __in_chrg=<optimized out>) at /usr/include/qt5/QtQml/qqmlprivate.h:108
#12 0x00007ffff5ce2380 in QObject::event (this=this@entry=0x10c2f60, e=e@entry=0x2b76cc0) at kernel/qobject.cpp:1252
#13 0x00007ffff77c2ae3 in QQuickItem::event (this=0x10c2f60, ev=0x2b76cc0) at items/qquickitem.cpp:8105
#14 0x00007ffff6711c42 in QApplicationPrivate::notify_helper (this=this@entry=0x4c14c0, receiver=receiver@entry=0x10c2f60, e=e@entry=0x2b76cc0) at kernel/qapplication.cpp:3700
#15 0x00007ffff671b1c0 in QApplication::notify (this=0x7fffffffd730, receiver=0x10c2f60, e=0x2b76cc0) at kernel/qapplication.cpp:3446
#16 0x00007ffff5cb7212 in QCoreApplication::notifyInternal2 (receiver=0x10c2f60, event=0x2b76cc0) at ../../src/corelib/kernel/qobject.h:142
#17 0x00007ffff5cb9e08 in QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x4b6330) at kernel/qcoreapplication.cpp:1825
#18 0x00007ffff5d0d963 in postEventSourceDispatch (s=0x51a7c0) at kernel/qeventdispatcher_glib.cpp:276
#19 0x00007ffff3b86c6d in g_main_dispatch (context=0x7fffe8005010) at ../glib/gmain.c:3179
#20 g_main_context_dispatch (context=context@entry=0x7fffe8005010) at ../glib/gmain.c:3844
#21 0x00007ffff3b86ef0 in g_main_context_iterate (context=context@entry=0x7fffe8005010, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/gmain.c:3917
#22 0x00007ffff3b86f7f in g_main_context_iteration (context=0x7fffe8005010, may_block=may_block@entry=1) at ../glib/gmain.c:3978
#23 0x00007ffff5d0cfa1 in QEventDispatcherGlib::processEvents (this=0x51b110, flags=...) at kernel/qeventdispatcher_glib.cpp:422
#24 0x00007ffff5cb5e9b in QEventLoop::exec (this=this@entry=0x7fffffffd5f0, flags=..., flags@entry=...) at ../../src/corelib/global/qflags.h:140
#25 0x00007ffff5cbd942 in QCoreApplication::exec () at ../../src/corelib/global/qflags.h:120
#26 0x00007ffff608ecbc in QGuiApplication::exec () at kernel/qguiapplication.cpp:1784
#27 0x00007ffff6711bb5 in QApplication::exec () at kernel/qapplication.cpp:2856
#28 0x000000000041f4f1 in main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/plasma-workspace-5.18.1/shell/main.cpp:228
(gdb) c</pre></div>
<p>As you may see, due to m_layout being a QPointer, which contains QWeakPointer, reference counter is decreased twice. If there is no QPointer, there is no double decrement and no issue. And m_layout doesn't become dangling pointer since object m_layout points to is created in qml and is not destroyed until desktop view is destroyed.</p>
<p>Thus, while this fix is not perfect, it definitely fixes current issue.<br />
But looking into it closely after additional investigation, I think it might be fixed using another approach: signals have to be disconnected so that signal to already deconstructed object wouldn't be called from it's parent class. I'll upload updated version.</p></div></div><br /><div><strong>REPOSITORY</strong><div><div>R120 Plasma Workspace</div></div></div><br /><div><strong>REVISION DETAIL</strong><div><a href="https://phabricator.kde.org/D27650">https://phabricator.kde.org/D27650</a></div></div><br /><div><strong>To: </strong>alnikiforov, ngraham, davidedmundson, mart<br /><strong>Cc: </strong>plasma-devel, Orage, LeGast00n, The-Feren-OS-Dev, cblack, jraleigh, zachus, fbampaloukas, GB_2, ragreen, ZrenBot, ngraham, himcesjf, lesliezhai, ali-mohamed, jensreuterberg, abetts, sebas, apol, ahiemstra, mart<br /></div>