Bug 445894 - Crash in KWin::DrmOutput::updateCursor -> malloc(): unsorted double linked list corrupted
Summary: Crash in KWin::DrmOutput::updateCursor -> malloc(): unsorted double linked li...
Status: RESOLVED FIXED
Alias: None
Product: kwin
Classification: Plasma
Component: platform-drm (show other bugs)
Version: 5.23.5
Platform: openSUSE Linux
: NOR crash
Target Milestone: ---
Assignee: KWin default assignee
URL:
Keywords:
: 446101 (view as bug list)
Depends on:
Blocks: 446101 449773
  Show dependency treegraph
 
Reported: 2021-11-22 06:37 UTC by Jiri Slaby
Modified: 2022-02-08 06:57 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
gdb's "bt full" of the crash (17.17 KB, text/plain)
2021-11-22 06:37 UTC, Jiri Slaby
Details
drm_info with TB (60.77 KB, text/plain)
2021-12-13 07:05 UTC, Jiri Slaby
Details
drm_info without TB (56.50 KB, text/plain)
2021-12-13 07:05 UTC, Jiri Slaby
Details
valgrind output (717.07 KB, text/plain)
2022-01-25 10:03 UTC, Jiri Slaby
Details
fix (501 bytes, patch)
2022-01-25 10:31 UTC, Jiri Slaby
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jiri Slaby 2021-11-22 06:37:00 UTC
Created attachment 143823 [details]
gdb's "bt full" of the crash

SUMMARY
A crash occurred during resume from suspend.

STEPS TO REPRODUCE
1. suspend notebook
2. connect thunderbolt with external monitor connected
3. resume notebook.
4. (rare) crash occurs

OBSERVED RESULT
> #0  __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
> #1  0x00007f3b21bb28e3 in __pthread_kill_internal (signo=6, threadid=<optimized out>) at pthread_kill.c:78
> #2  0x00007f3b21b656f6 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
> #3  0x00007f3b21b4f845 in __GI_abort () at abort.c:100
> #4  0x00007f3b21ba6a67 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7f3b21ce369f "%s\n") at ../sysdeps/posix/libc_fatal.c:155
> #5  0x00007f3b21bbc86c in malloc_printerr (str=str@entry=0x7f3b21ce6788 "malloc(): unsorted double linked list corrupted") at malloc.c:5543
> #6  0x00007f3b21bbf89c in _int_malloc (av=av@entry=0x7f3b21d1daa0 <main_arena>, bytes=bytes@entry=1040) at malloc.c:3897
> #7  0x00007f3b21bc06d9 in __GI___libc_malloc (bytes=1040) at malloc.c:3216
> #8  0x00007f3b21de296c in operator new(unsigned long) (sz=1040) at ../../../../libstdc++-v3/libsupc++/new_op.cc:50
> #9  0x00007f3b22b54262 in QRasterPaintEngine::createState(QPainterState*) const () at /lib64/libQt5Gui.so.5
> #10 0x00007f3b22b70c56 in QPainter::begin(QPaintDevice*) () at /lib64/libQt5Gui.so.5
> #11 0x00007f3b1bb717cb in KWin::DrmOutput::updateCursor() (this=0x5596f79cc0d0) at /usr/src/debug/kwin5-5.23.2-2.1.x86_64/src/plugins/platforms/drm/drm_output.cpp:150
> #12 0x00007f3b1bb62527 in KWin::DrmBackend::updateCursor() (this=0x5596f71d0210) at /usr/src/debug/kwin5-5.23.2-2.1.x86_64/src/plugins/platforms/drm/drm_backend.cpp:571
> #13 0x00007f3b1bb69071 in KWin::DrmBackend::handleUdevEvent() (this=0x5596f71d0210) at /usr/src/debug/kwin5-5.23.2-2.1.x86_64/src/plugins/platforms/drm/drm_backend.cpp:245
> #14 0x00007f3b2246e043 in QtPrivate::QSlotObjectBase::call(QObject*, void**) (a=0x7ffc38c73d50, r=0x5596f71d0210, this=0x5596f71db7a0) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398
> #15 doActivate<false>(QObject*, int, void**) (sender=0x5596f71db4a0, signal_index=3, argv=0x7ffc38c73d50) at kernel/qobject.cpp:3886
> #16 0x00007f3b2246750f in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (sender=sender@entry=0x5596f71db4a0, m=m@entry=0x7f3b2270dac0, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7ffc38c73d50) at kernel/qobject.cpp:3946
> #17 0x00007f3b2247141f in QSocketNotifier::activated(QSocketDescriptor, QSocketNotifier::Type, QSocketNotifier::QPrivateSignal) (this=this@entry=0x5596f71db4a0, _t1=..., _t2=<optimized out>, _t3=...) at .moc/moc_qsocketnotifier.cpp:178
> #18 0x00007f3b22471c1b in QSocketNotifier::event(QEvent*) (this=0x5596f71db4a0, e=0x7ffc38c73e70) at kernel/qsocketnotifier.cpp:302
> #19 0x00007f3b2318fa7f in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=<optimized out>, receiver=0x5596f71db4a0, e=0x7ffc38c73e70) at kernel/qapplication.cpp:3632
> #20 0x00007f3b224379fa in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x5596f71db4a0, event=0x7ffc38c73e70) at kernel/qcoreapplication.cpp:1064
> #21 0x00007f3b2248c28b in QEventDispatcherUNIXPrivate::activateSocketNotifiers() (this=0x5596f71755c0) at kernel/qeventdispatcher_unix.cpp:304
> #22 0x00007f3b2248c6eb in QEventDispatcherUNIX::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=<optimized out>, flags=...) at kernel/qeventdispatcher_unix.cpp:511
> #23 0x00005596f70ab39d in QUnixEventDispatcherQPA::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=<optimized out>, flags=...) at qunixeventdispatcher.cpp:63
> #24 0x00007f3b224363fb in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (this=this@entry=0x7ffc38c74000, flags=..., flags@entry=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:69
> #25 0x00007f3b2243e6e0 in QCoreApplication::exec() () at ../../include/QtCore/../../src/corelib/global/qflags.h:121
> #26 0x00005596f704e625 in main(int, char**) (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/kwin5-5.23.2-2.1.x86_64/src/main_wayland.cpp:745

SOFTWARE/OS VERSIONS
Operating System: openSUSE Tumbleweed 20211117
KDE Plasma Version: 5.23.2
KDE Frameworks Version: 5.87.0
Qt Version: 5.15.2
Kernel Version: 5.15.2-1.g26a203b-default (64-bit)
Graphics Platform: Wayland
Processors: 4 × Intel® Core™ i7-6600U CPU @ 2.60GHz
Memory: 15.3 GiB of RAM
Graphics Processor: Mesa Intel® HD Graphics 520
Comment 1 Zamundaaa 2021-12-07 09:25:35 UTC
Please attach the output of drm_info, once with the thunderbolt device connected, and once without
Comment 2 Jiri Slaby 2021-12-13 07:05:22 UTC
Created attachment 144499 [details]
drm_info with TB
Comment 3 Jiri Slaby 2021-12-13 07:05:45 UTC
Created attachment 144500 [details]
drm_info without TB
Comment 4 Jiri Slaby 2021-12-13 07:07:59 UTC
Today I encountered a little different crash: a bit different stack trace. But still a heap corruption and still KWin::DrmGpu::updateOutputs is common.

> #5  0x00007f9fea02fe8c in malloc_printerr (str=str@entry=0x7f9fea1616d0 "malloc(): smallbin double linked list corrupted") at malloc.c:5543
> #6  0x00007f9fea0332dc in _int_malloc (av=av@entry=0x7f9fea198aa0 <main_arena>, bytes=bytes@entry=129) at malloc.c:3797
> #7  0x00007f9fea0338fa in _int_realloc (av=av@entry=0x7f9fea198aa0 <main_arena>, oldp=oldp@entry=0x55ac9a1aa920, oldsize=80, nb=144) at malloc.c:4765
> #8  0x00007f9fea03472b in __GI___libc_realloc (oldmem=0x55ac9a1aa930, bytes=128) at malloc.c:3381
> #9  0x00007f9fea6dd25c in reallocateData (options=8, allocSize=<optimized out>, header=0x55ac9a1aa930) at tools/qarraydata.cpp:183
> #10 QArrayData::reallocateUnaligned(QArrayData*, unsigned long, unsigned long, QFlags<QArrayData::AllocationOption>) (data=0x55ac9a1aa930, objectSize=objectSize@entry=2, capacity=52, options=...) at tools/qarraydata.cpp:246
> #11 0x00007f9fea7532f2 in QTypedArrayData<unsigned short>::reallocateUnaligned(QTypedArrayData<unsigned short>*, unsigned long, QFlags<QArrayData::AllocationOption>) (options=..., capacity=25, data=<optimized out>) at ../../include/QtCore/../../src/corelib/tools/qarraydata.h:228
> #12 QString::reallocData(unsigned int, bool) (this=0x7ffd926347f8, alloc=25, grow=<optimized out>) at text/qstring.cpp:2375
> #13 0x00007f9fea753862 in QString::append(QString const&) (this=this@entry=0x7ffd926347f8, str=...) at text/qstring.cpp:2684
> #14 0x00007f9fea6cd0ad in qFormatLogMessage(QtMsgType, QMessageLogContext const&, QString const&) (type=<optimized out>, context=<optimized out>, str=<optimized out>) at global/qlogging.cpp:1414
> #15 0x00007f9fea6cddaf in stderr_message_handler (message=<optimized out>, context=<optimized out>, type=<optimized out>) at global/qlogging.cpp:1742
> #16 qDefaultMessageHandler(QtMsgType, QMessageLogContext const&, QString const&) (type=QtWarningMsg, context=..., message=...) at global/qlogging.cpp:1786
> #17 0x00007f9fea6c9a60 in qt_message_print(QtMsgType, QMessageLogContext const&, QString const&) (msgType=QtWarningMsg, context=..., message=...) at global/qlogging.cpp:1843
> #18 0x00007f9fea6cafdb in qt_message_output(QtMsgType, QMessageLogContext const&, QString const&) (msgType=QtWarningMsg, context=..., message=...) at global/qlogging.cpp:1924
> #19 0x00007f9fea7cbaa8 in QDebug::~QDebug() (this=0x7ffd926348d8, __in_chrg=<optimized out>) at io/qdebug.cpp:154
> #20 QDebug::~QDebug() (this=0x7ffd926348d8, __in_chrg=<optimized out>) at io/qdebug.cpp:148
> #21 0x00007f9fe3ef8282 in KWin::DrmPipeline::printDebugInfo() const (this=0x55ac99e04190) at /usr/src/debug/kwin5-5.23.3-1.1.x86_64/src/plugins/platforms/drm/drm_pipeline.cpp:634
> #22 0x00007f9fe3ef8408 in operator()() const (__closure=__closure@entry=0x7ffd926349f0) at /usr/src/debug/kwin5-5.23.3-1.1.x86_64/src/plugins/platforms/drm/drm_pipeline.cpp:134
> #23 0x00007f9fe3efacb4 in KWin::DrmPipeline::commitPipelines(QVector<KWin::DrmPipeline*> const&, KWin::DrmPipeline::CommitMode) (pipelines=..., mode=KWin::DrmPipeline::CommitMode::Test) at /usr/src/debug/kwin5-5.23.3-1.1.x86_64/src/plugins/platforms/drm/drm_pipeline.cpp:161
> #24 0x00007f9fe3ef20f6 in KWin::DrmGpu::commitCombination(QVector<KWin::DrmPipeline*> const&) (pipelines=..., this=<optimized out>) at /usr/src/debug/kwin5-5.23.3-1.1.x86_64/src/plugins/platforms/drm/drm_gpu.cpp:373
> #25 KWin::DrmGpu::findWorkingCombination(QVector<KWin::DrmPipeline*> const&, QVector<KWin::DrmConnector*>, QVector<KWin::DrmCrtc*>, QVector<KWin::DrmPlane*> const&) (this=<optimized out>, pipelines=..., connectors=..., crtcs=..., planes=...)
>     at /usr/src/debug/kwin5-5.23.3-1.1.x86_64/src/plugins/platforms/drm/drm_gpu.cpp:302
> #26 0x00007f9fe3ef2e4d in operator()(KWin::DrmCrtc*, KWin::DrmPlane*) const (__closure=__closure@entry=0x7ffd92634d70, crtc=0x55ac964765e0, primaryPlane=<optimized out>) at /usr/src/debug/kwin5-5.23.3-1.1.x86_64/src/plugins/platforms/drm/drm_gpu.cpp:331
> #27 0x00007f9fe3ef26dd in KWin::DrmGpu::findWorkingCombination(QVector<KWin::DrmPipeline*> const&, QVector<KWin::DrmConnector*>, QVector<KWin::DrmCrtc*>, QVector<KWin::DrmPlane*> const&) (this=0x55ac963d3870, pipelines=..., connectors=..., crtcs=..., planes=...)
>     at /usr/src/debug/kwin5-5.23.3-1.1.x86_64/src/plugins/platforms/drm/drm_gpu.cpp:344
> #28 0x00007f9fe3ef2e4d in operator()(KWin::DrmCrtc*, KWin::DrmPlane*) const (__closure=__closure@entry=0x7ffd92635020, crtc=0x55ac96475ee0, primaryPlane=<optimized out>) at /usr/src/debug/kwin5-5.23.3-1.1.x86_64/src/plugins/platforms/drm/drm_gpu.cpp:331
> #29 0x00007f9fe3ef26dd in KWin::DrmGpu::findWorkingCombination(QVector<KWin::DrmPipeline*> const&, QVector<KWin::DrmConnector*>, QVector<KWin::DrmCrtc*>, QVector<KWin::DrmPlane*> const&) (this=0x55ac963d3870, pipelines=<optimized out>, connectors=..., crtcs=..., planes=...)
>     at /usr/src/debug/kwin5-5.23.3-1.1.x86_64/src/plugins/platforms/drm/drm_gpu.cpp:344
> #30 0x00007f9fe3edf742 in KWin::DrmGpu::updateOutputs() (this=<optimized out>) at /usr/src/debug/kwin5-5.23.3-1.1.x86_64/src/plugins/platforms/drm/drm_gpu.cpp:256
> #31 KWin::DrmBackend::updateOutputs() (this=<optimized out>) at /usr/src/debug/kwin5-5.23.3-1.1.x86_64/src/plugins/platforms/drm/drm_backend.cpp:355
> #32 0x00007f9fe3ee2059 in KWin::DrmBackend::handleUdevEvent() (this=0x55ac963b8aa0) at /usr/src/debug/kwin5-5.23.3-1.1.x86_64/src/plugins/platforms/drm/drm_backend.cpp:244
> #33 0x00007f9fea8ed043 in QtPrivate::QSlotObjectBase::call(QObject*, void**) (a=0x7ffd926356a0, r=0x55ac963b8aa0, this=0x55ac963d32e0) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398
> #34 doActivate<false>(QObject*, int, void**) (sender=0x55ac963d2fe0, signal_index=3, argv=0x7ffd926356a0) at kernel/qobject.cpp:3886
> #35 0x00007f9fea8e650f in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (sender=sender@entry=0x55ac963d2fe0, m=m@entry=0x7f9feab8cac0, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7ffd926356a0) at kernel/qobject.cpp:3946
> #36 0x00007f9fea8f041f in QSocketNotifier::activated(QSocketDescriptor, QSocketNotifier::Type, QSocketNotifier::QPrivateSignal) (this=this@entry=0x55ac963d2fe0, _t1=..., _t2=<optimized out>, _t3=...) at .moc/moc_qsocketnotifier.cpp:178
> #37 0x00007f9fea8f0c1b in QSocketNotifier::event(QEvent*) (this=0x55ac963d2fe0, e=0x7ffd926357c0) at kernel/qsocketnotifier.cpp:302
> #38 0x00007f9feb611a7f in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=<optimized out>, receiver=0x55ac963d2fe0, e=0x7ffd926357c0) at kernel/qapplication.cpp:3632
> #39 0x00007f9fea8b69fa in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x55ac963d2fe0, event=0x7ffd926357c0) at kernel/qcoreapplication.cpp:1064
> #40 0x00007f9fea90b28b in QEventDispatcherUNIXPrivate::activateSocketNotifiers() (this=0x55ac9636c670) at kernel/qeventdispatcher_unix.cpp:304
> #41 0x00007f9fea90b6eb in QEventDispatcherUNIX::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=<optimized out>, flags=...) at kernel/qeventdispatcher_unix.cpp:511
> #42 0x000055ac94a283bd in QUnixEventDispatcherQPA::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=<optimized out>, flags=...) at qunixeventdispatcher.cpp:63
> #43 0x00007f9fea8b53fb in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (this=this@entry=0x7ffd92635950, flags=..., flags@entry=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:69
> #44 0x00007f9fea8bd6e0 in QCoreApplication::exec() () at ../../include/QtCore/../../src/corelib/global/qflags.h:121
> #45 0x00007f9fead0918c in QGuiApplication::exec() () at kernel/qguiapplication.cpp:1867
> #46 0x00007f9feb6119f5 in QApplication::exec() () at kernel/qapplication.cpp:2824
> #47 0x000055ac949cb625 in main(int, char**) (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/kwin5-5.23.3-1.1.x86_64/src/main_wayland.cpp:745
Comment 5 Zamundaaa 2021-12-14 08:39:44 UTC
If you plug in and out without suspend, does that ever cause problems?
Comment 6 Jiri Slaby 2021-12-16 20:35:13 UTC
(In reply to Zamundaaa from comment #5)
> If you plug in and out without suspend, does that ever cause problems?

Yes, sometimes -- still under KWin::DrmBackend::updateCursor() and further.

Note that even if it doesn't crash, the secondary monitor output is always frozen after re-plug. I have to switch to a tty and back to have it redrawn (happens with suspend too). I don't even see a mouse pointer on that monitor otherwise.
Comment 7 Vlad Zahorodnii 2022-01-24 11:22:34 UTC
Most likely, kwin overwrites the data it shouldn't. It would be great if you could run kwin with valgrind, but it can make the computer very unusable.
Comment 8 Jiri Slaby 2022-01-25 08:56:28 UTC
(In reply to Vlad Zahorodnii from comment #7)
> Most likely, kwin overwrites the data it shouldn't. It would be great if you
> could run kwin with valgrind, but it can make the computer very unusable.

You'd have to tell me how. kwin_wayland has cap_sys_nice=ep caps set. So if I wrap it by valgrind I get:
> ==31896== 
> ==31896== Warning: Can't execute setuid/setgid/setcap executable: /usr/bin/kwin_wayland
> ==31896== Possible workaround: remove --trace-children=yes, if in effect
> ==31896== 
> valgrind: /usr/bin/kwin_wayland: Permission denied

If I unset those caps and create a wrapper:
#!/bin/bash

exec valgrind --log-file=/tmp/kwin_valgrind kwin_wayland.exe
and set those caps to the wrapper (adding inheritance too):
setcap cap_sys_nice=epi kwin_wayland

It doesn't start. Changing valgrind to strace in that script shows, that it dies likely due to this:
26687 sched_setscheduler(0, SCHED_RR, 0x7ffd37879530) = -1 EPERM 

So the caps are not really inherited. Maybe ptrace() in valgrind/strace removes those caps.
Comment 9 Vlad Zahorodnii 2022-01-25 09:24:16 UTC
You can temporarily remove the capabilities by using setcap -r. When you're done, sudo setcap CAP_SYS_NICE=+ep /path/to/kwin_wayland
Comment 10 Jiri Slaby 2022-01-25 09:30:28 UTC
(In reply to Vlad Zahorodnii from comment #9)
> You can temporarily remove the capabilities by using setcap -r. When you're
> done, sudo setcap CAP_SYS_NICE=+ep /path/to/kwin_wayland

As I wrote, that quits after:
> 26687 sched_setscheduler(0, SCHED_RR, 0x7ffd37879530) = -1 EPERM
Comment 11 Vlad Zahorodnii 2022-01-25 09:44:48 UTC
That's odd. kwin_wayland should start without the nice capability, most kwin devs run kwin like that. Maybe kwin_wayland_wrapper doesn't like the wrapper around kwin_wayland.

Can you try running kwin from VT?

export XDG_SESSION_TYPE=wayland
eval $(dbus-launch)
[start tmux or screen maybe]
valgrind kwin_wayland --exit-with-session=konsole
Comment 12 Jiri Slaby 2022-01-25 10:03:34 UTC
Created attachment 145901 [details]
valgrind output

Looks promising (complete log attached):
> ==3522== Invalid read of size 1
> ==3522==    at 0xCEAD79C: KWin::DrmPipeline::setCursor(QSharedPointer<KWin::DrmDumbBuffer> const&, QPoint const&) (drm_pipeline.cpp:324)
> ==3522==    by 0xCE9AABE: KWin::DrmOutput::showCursor() (drm_output.cpp:108)
> ==3522==    by 0xCE9ADFD: KWin::DrmOutput::updateTransform(KWin::AbstractOutput::Transform) (drm_output.cpp:323)
> ==3522==    by 0xCE9692B: KWin::DrmBackend::updateOutputs() (drm_gpu.cpp:276)
> ==3522==    by 0xCE990B8: KWin::DrmBackend::handleUdevEvent() (drm_backend.cpp:244)
> ==3522==    by 0x6502422: UnknownInlinedFun (qobjectdefs_impl.h:398)
> ==3522==    by 0x6502422: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
> ==3522==    by 0x65057FE: QSocketNotifier::activated(QSocketDescriptor, QSocketNotifier::Type, QSocketNotifier::QPrivateSignal) (moc_qsocketnotifier.cpp:178)
> ==3522==    by 0x6505FFA: QSocketNotifier::event(QEvent*) (qsocketnotifier.cpp:302)
> ==3522==    by 0x53CEA7E: QApplicationPrivate::notify_helper(QObject*, QEvent*) (qapplication.cpp:3632)
> ==3522==    by 0x64CBDB9: QCoreApplication::notifyInternal2(QObject*, QEvent*) (qcoreapplication.cpp:1064)
> ==3522==    by 0x652065A: QEventDispatcherUNIXPrivate::activateSocketNotifiers() (qeventdispatcher_unix.cpp:304)
> ==3522==    by 0x6520ABA: QEventDispatcherUNIX::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (qeventdispatcher_unix.cpp:511)
> ==3522==  Address 0x1b65e4d0 is 112 bytes inside a block of size 136 free'd
> ==3522==    at 0x484699B: operator delete(void*, unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==3522==    by 0xCEA9EEC: KWin::DrmGpu::findWorkingCombination(QVector<KWin::DrmPipeline*> const&, QVector<KWin::DrmConnector*>, QVector<KWin::DrmCrtc*>, QVector<KWin::DrmPlane*> const&)::{lambda(KWin::DrmCrtc*, KWin::DrmPlane*)#2}::operator()(KWin::DrmCrtc*, KWin::DrmPlane*) const (drm_gpu.cpp:333)
> ==3522==    by 0xCEA970C: KWin::DrmGpu::findWorkingCombination(QVector<KWin::DrmPipeline*> const&, QVector<KWin::DrmConnector*>, QVector<KWin::DrmCrtc*>, QVector<KWin::DrmPlane*> const&) (drm_gpu.cpp:344)
> ==3522==    by 0xCE96791: KWin::DrmBackend::updateOutputs() (drm_gpu.cpp:256)
> ==3522==    by 0xCE990B8: KWin::DrmBackend::handleUdevEvent() (drm_backend.cpp:244)
> ==3522==    by 0x6502422: UnknownInlinedFun (qobjectdefs_impl.h:398)
> ==3522==    by 0x6502422: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
> ==3522==    by 0x65057FE: QSocketNotifier::activated(QSocketDescriptor, QSocketNotifier::Type, QSocketNotifier::QPrivateSignal) (moc_qsocketnotifier.cpp:178)
> ==3522==    by 0x6505FFA: QSocketNotifier::event(QEvent*) (qsocketnotifier.cpp:302)
> ==3522==    by 0x53CEA7E: QApplicationPrivate::notify_helper(QObject*, QEvent*) (qapplication.cpp:3632)
> ==3522==    by 0x64CBDB9: QCoreApplication::notifyInternal2(QObject*, QEvent*) (qcoreapplication.cpp:1064)
> ==3522==    by 0x652065A: QEventDispatcherUNIXPrivate::activateSocketNotifiers() (qeventdispatcher_unix.cpp:304)
> ==3522==    by 0x6520ABA: QEventDispatcherUNIX::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (qeventdispatcher_unix.cpp:511)
> ==3522==  Block was alloc'd at
> ==3522==    at 0x4843F2F: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==3522==    by 0xCEA9C78: KWin::DrmGpu::findWorkingCombination(QVector<KWin::DrmPipeline*> const&, QVector<KWin::DrmConnector*>, QVector<KWin::DrmCrtc*>, QVector<KWin::DrmPlane*> const&)::{lambda(KWin::DrmCrtc*, KWin::DrmPlane*)#2}::operator()(KWin::DrmCrtc*, KWin::DrmPlane*) const (drm_gpu.cpp:324)
> ==3522==    by 0xCEA970C: KWin::DrmGpu::findWorkingCombination(QVector<KWin::DrmPipeline*> const&, QVector<KWin::DrmConnector*>, QVector<KWin::DrmCrtc*>, QVector<KWin::DrmPlane*> const&) (drm_gpu.cpp:344)
> ==3522==    by 0xCE96791: KWin::DrmBackend::updateOutputs() (drm_gpu.cpp:256)
> ==3522==    by 0xCE990B8: KWin::DrmBackend::handleUdevEvent() (drm_backend.cpp:244)
> ==3522==    by 0x6502422: UnknownInlinedFun (qobjectdefs_impl.h:398)
> ==3522==    by 0x6502422: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
> ==3522==    by 0x65057FE: QSocketNotifier::activated(QSocketDescriptor, QSocketNotifier::Type, QSocketNotifier::QPrivateSignal) (moc_qsocketnotifier.cpp:178)
> ==3522==    by 0x6505FFA: QSocketNotifier::event(QEvent*) (qsocketnotifier.cpp:302)
> ==3522==    by 0x53CEA7E: QApplicationPrivate::notify_helper(QObject*, QEvent*) (qapplication.cpp:3632)
> ==3522==    by 0x64CBDB9: QCoreApplication::notifyInternal2(QObject*, QEvent*) (qcoreapplication.cpp:1064)
> ==3522==    by 0x652065A: QEventDispatcherUNIXPrivate::activateSocketNotifiers() (qeventdispatcher_unix.cpp:304)
> ==3522==    by 0x6520ABA: QEventDispatcherUNIX::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (qeventdispatcher_unix.cpp:511)
Comment 13 Jiri Slaby 2022-01-25 10:09:50 UTC
Shouldn't the delete in DrmGpu::findWorkingCombination be preceded by allPipelines.removeLast() (or something like that)?
Comment 14 Jiri Slaby 2022-01-25 10:31:35 UTC
Created attachment 145902 [details]
fix

This DrmGpu::findWorkingCombination code is completely gone in master since:
commit e2a0863843f92ab1f2f8d0c785a86570fc04d774
Author: Xaver Hugl <xaver.hugl@gmail.com>
Date:   Tue Sep 28 10:29:56 2021 +0200

    platforms/drm: more dynamic crtc assignment


Anyway, if I do this in 5.23.5, it seems to fix the problem.
Comment 15 Vlad Zahorodnii 2022-01-26 15:53:36 UTC
Can you confirm that this issue is gone in 5.24 beta?
Comment 16 Jiri Slaby 2022-01-28 09:05:15 UTC
(In reply to Vlad Zahorodnii from comment #15)
> Can you confirm that this issue is gone in 5.24 beta?

Waiting for beta to reach factory (a couple of days, I assume):
https://build.opensuse.org/request/show/947521
Comment 17 Jiri Slaby 2022-01-31 07:10:20 UTC
(In reply to Jiri Slaby from comment #14)
> Anyway, if I do this in 5.23.5, it seems to fix the problem.

Not completely, kwin still crashes, but elsewhere. Still memory corruption. Still waiting for 5.24 beta to reach factory. Just for completeness:
> #5  0x00007f8a202cbe3c in malloc_printerr (str=str@entry=0x7f8a203fd6d0 "malloc(): smallbin double linked list corrupted") at malloc.c:5543
> #6  0x00007f8a202cf28c in _int_malloc (av=av@entry=0x7f8a20434aa0 <main_arena>, bytes=bytes@entry=129) at malloc.c:3797
> #7  0x00007f8a202cf8aa in _int_realloc (av=av@entry=0x7f8a20434aa0 <main_arena>, oldp=oldp@entry=0x55cf650a0900, oldsize=80, nb=144) at malloc.c:4765
> #8  0x00007f8a202d06db in __GI___libc_realloc (oldmem=0x55cf650a0910, bytes=128) at malloc.c:3381
> #9  0x00007f8a2097c2ac in reallocateData (options=8, allocSize=<optimized out>, header=0x55cf650a0910) at tools/qarraydata.cpp:183
> #10 QArrayData::reallocateUnaligned(QArrayData*, unsigned long, unsigned long, QFlags<QArrayData::AllocationOption>) (data=0x55cf650a0910, objectSize=objectSize@entry=2, capacity=52, options=...) at tools/qarraydata.cpp:246
> #11 0x00007f8a209f2352 in QTypedArrayData<unsigned short>::reallocateUnaligned(QTypedArrayData<unsigned short>*, unsigned long, QFlags<QArrayData::AllocationOption>) (options=..., capacity=29, data=<optimized out>) at ../../include/QtCore/../../src/corelib/tools/qarraydata.h:228
> #12 QString::reallocData(unsigned int, bool) (this=0x7ffeea702398, alloc=29, grow=<optimized out>) at text/qstring.cpp:2375
> #13 0x00007f8a209f28c2 in QString::append(QString const&) (this=this@entry=0x7ffeea702398, str=...) at text/qstring.cpp:2684
> #14 0x00007f8a2096c0dd in qFormatLogMessage(QtMsgType, QMessageLogContext const&, QString const&) (type=<optimized out>, context=<optimized out>, str=<optimized out>) at global/qlogging.cpp:1414
> #15 0x00007f8a2096cddf in stderr_message_handler (message=<optimized out>, context=<optimized out>, type=<optimized out>) at global/qlogging.cpp:1742
> #16 qDefaultMessageHandler(QtMsgType, QMessageLogContext const&, QString const&) (type=QtWarningMsg, context=..., message=...) at global/qlogging.cpp:1786
> #17 0x00007f8a20968a90 in qt_message_print(QtMsgType, QMessageLogContext const&, QString const&) (msgType=QtWarningMsg, context=..., message=...) at global/qlogging.cpp:1843
> #18 0x00007f8a2096a00b in qt_message_output(QtMsgType, QMessageLogContext const&, QString const&) (msgType=QtWarningMsg, context=..., message=...) at global/qlogging.cpp:1924
> #19 0x00007f8a20a6ab88 in QDebug::~QDebug() (this=0x7ffeea702490, __in_chrg=<optimized out>) at io/qdebug.cpp:154
> #20 QDebug::~QDebug() (this=0x7ffeea702490, __in_chrg=<optimized out>) at io/qdebug.cpp:148
> #21 0x00007f8a1a14eab3 in KWin::printProps(KWin::DrmObject*) (object=<optimized out>) at /usr/src/debug/kwin5-5.23.5-6.1.x86_64/src/plugins/platforms/drm/drm_pipeline.cpp:621
> #22 0x00007f8a1a152ef5 in KWin::DrmPipeline::printDebugInfo() const (this=0x55cf644ee3b0) at /usr/src/debug/kwin5-5.23.5-6.1.x86_64/src/plugins/platforms/drm/drm_pipeline.cpp:647
> #23 0x00007f8a1a153428 in operator()() const (__closure=__closure@entry=0x7ffeea702630) at /usr/src/debug/kwin5-5.23.5-6.1.x86_64/src/plugins/platforms/drm/drm_pipeline.cpp:134
> #24 0x00007f8a1a155cd4 in KWin::DrmPipeline::commitPipelines(QVector<KWin::DrmPipeline*> const&, KWin::DrmPipeline::CommitMode) (pipelines=..., mode=KWin::DrmPipeline::CommitMode::Test) at /usr/src/debug/kwin5-5.23.5-6.1.x86_64/src/plugins/platforms/drm/drm_pipeline.cpp:161
> #25 0x00007f8a1a14d056 in KWin::DrmGpu::commitCombination(QVector<KWin::DrmPipeline*> const&) (pipelines=..., this=<optimized out>) at /usr/src/debug/kwin5-5.23.5-6.1.x86_64/src/plugins/platforms/drm/drm_gpu.cpp:374
> #26 KWin::DrmGpu::findWorkingCombination(QVector<KWin::DrmPipeline*> const&, QVector<KWin::DrmConnector*>, QVector<KWin::DrmCrtc*>, QVector<KWin::DrmPlane*> const&) (this=<optimized out>, pipelines=..., connectors=..., crtcs=..., planes=...)
>     at /usr/src/debug/kwin5-5.23.5-6.1.x86_64/src/plugins/platforms/drm/drm_gpu.cpp:302
> #27 0x00007f8a1a14de63 in operator()(KWin::DrmCrtc*, KWin::DrmPlane*) const (__closure=__closure@entry=0x7ffeea7029b0, crtc=<optimized out>, primaryPlane=<optimized out>) at /usr/src/debug/kwin5-5.23.5-6.1.x86_64/src/plugins/platforms/drm/drm_gpu.cpp:331
> #28 0x00007f8a1a14d655 in KWin::DrmGpu::findWorkingCombination(QVector<KWin::DrmPipeline*> const&, QVector<KWin::DrmConnector*>, QVector<KWin::DrmCrtc*>, QVector<KWin::DrmPlane*> const&) (this=0x55cf631391e0, pipelines=..., connectors=..., crtcs=..., planes=...)
>     at /usr/src/debug/kwin5-5.23.5-6.1.x86_64/src/plugins/platforms/drm/drm_gpu.cpp:345
> #29 0x00007f8a1a14de63 in operator()(KWin::DrmCrtc*, KWin::DrmPlane*) const (__closure=__closure@entry=0x7ffeea702c60, crtc=<optimized out>, primaryPlane=<optimized out>) at /usr/src/debug/kwin5-5.23.5-6.1.x86_64/src/plugins/platforms/drm/drm_gpu.cpp:331
> #30 0x00007f8a1a14d655 in KWin::DrmGpu::findWorkingCombination(QVector<KWin::DrmPipeline*> const&, QVector<KWin::DrmConnector*>, QVector<KWin::DrmCrtc*>, QVector<KWin::DrmPlane*> const&) (this=0x55cf631391e0, pipelines=<optimized out>, connectors=..., crtcs=..., planes=...)
>     at /usr/src/debug/kwin5-5.23.5-6.1.x86_64/src/plugins/platforms/drm/drm_gpu.cpp:345
> #31 0x00007f8a1a13a766 in KWin::DrmGpu::updateOutputs() (this=<optimized out>) at /usr/src/debug/kwin5-5.23.5-6.1.x86_64/src/plugins/platforms/drm/drm_gpu.cpp:256
> #32 KWin::DrmBackend::updateOutputs() (this=<optimized out>) at /usr/src/debug/kwin5-5.23.5-6.1.x86_64/src/plugins/platforms/drm/drm_backend.cpp:356
Comment 18 Jiri Slaby 2022-01-31 09:42:19 UTC
(In reply to Jiri Slaby from comment #16)
> (In reply to Vlad Zahorodnii from comment #15)
> > Can you confirm that this issue is gone in 5.24 beta?
> 
> Waiting for beta to reach factory (a couple of days, I assume):
> https://build.opensuse.org/request/show/947521

OK, so I updated from KDE:Frameworks5. That means I am at v5.23.90 + some patches. The crash seems to be gone, but I see this now:
> ==2431== Conditional jump or move depends on uninitialised value(s)
> ==2431==    at 0xCD2C5FF: KWin::DrmPipeline::checkTestBuffer()::{lambda(QSharedPointer<KWin::DrmBuffer> const&)#1}::operator()(QSharedPointer<KWin::DrmBuffer> const&) const (drm_pipeline.cpp:302)
> ==2431==    by 0xCD2C7E0: KWin::DrmPipeline::checkTestBuffer() (drm_pipeline.cpp:315)
> ==2431==    by 0xCD2CCF8: KWin::DrmPipeline::commitPipelinesAtomic(QVector<KWin::DrmPipeline*> const&, KWin::DrmPipeline::CommitMode, QVector<KWin::DrmObject*> const&) (drm_pipeline.cpp:131)
> ==2431==    by 0xCD249A8: KWin::DrmGpu::testPipelines() (drm_gpu.cpp:427)
> ==2431==    by 0xCD26A67: KWin::DrmGpu::checkCrtcAssignment(QVector<KWin::DrmConnector*>, QVector<KWin::DrmCrtc*>) (drm_gpu.cpp:365)
> ==2431==    by 0xCD26A67: KWin::DrmGpu::checkCrtcAssignment(QVector<KWin::DrmConnector*>, QVector<KWin::DrmCrtc*>) (drm_gpu.cpp:365)
> ==2431==    by 0xCD39878: UnknownInlinedFun (drm_gpu.cpp:398)
> ==2431==    by 0xCD39878: UnknownInlinedFun (drm_gpu.cpp:396)
> ==2431==    by 0xCD39878: KWin::DrmGpu::testPendingConfiguration(KWin::DrmGpu::TestMode) [clone .constprop.0] (drm_gpu.cpp:403)
> ==2431==    by 0xCD13573: KWin::DrmBackend::updateOutputs() (drm_gpu.cpp:309)
Comment 19 Jiri Slaby 2022-01-31 09:44:51 UTC
*** Bug 446101 has been marked as a duplicate of this bug. ***
Comment 20 Vlad Zahorodnii 2022-02-04 15:22:13 UTC
Not sure what valgrind doesn't like, I don't see issues with that code right off the bat.
Comment 21 Jiri Slaby 2022-02-07 06:58:00 UTC
(In reply to Vlad Zahorodnii from comment #20)
> Not sure what valgrind doesn't like, I don't see issues with that code right
> off the bat.

I reorganized the conditions to one per line:
>   303     const auto &checkBuffer = [this, backend, &buffer](const QSharedPointer<DrmBuffer> &buf){
>   304         const auto &mods = supportedModifiers(buf->format());
>   305         if (backend)
>   306                 if (buf->format() == backend->drmFormat(m_output))
>   307                         if (mods.isEmpty() || mods.contains(buf->modifier()))
>   308                                 if (buf->size() == bufferSize())
>   309                                         buffer = buf;
>   310     };

And added --track-origins=yes to valgrind (the last 2 lines are new):
> Conditional jump or move depends on uninitialised value(s)
>    at 0xCD2EBCF: KWin::DrmPipeline::checkTestBuffer()::{lambda(QSharedPointer<KWin::DrmBuffer> const&)#1}::operator()(QSharedPointer<KWin::DrmBuffer> const&) const (drm_pipeline.cpp:306)
>    by 0xCD2EDA3: KWin::DrmPipeline::checkTestBuffer() (drm_pipeline.cpp:318)
>    by 0xCD2F41E: KWin::DrmPipeline::commitPipelinesAtomic(QVector<KWin::DrmPipeline*> const&, KWin::DrmPipeline::CommitMode, QVector<KWin::DrmObject*> const&) (drm_pipeline.cpp:131)
>    by 0xCD26BA8: KWin::DrmGpu::testPipelines() (drm_gpu.cpp:427)
>    by 0xCD29E27: KWin::DrmGpu::checkCrtcAssignment(QVector<KWin::DrmConnector*>, QVector<KWin::DrmCrtc*>) (drm_gpu.cpp:365)
>    by 0xCD29E27: KWin::DrmGpu::checkCrtcAssignment(QVector<KWin::DrmConnector*>, QVector<KWin::DrmCrtc*>) (drm_gpu.cpp:365)
>    by 0xCD3B298: UnknownInlinedFun (drm_gpu.cpp:398)
>    by 0xCD3B298: UnknownInlinedFun (drm_gpu.cpp:396)
>    by 0xCD3B298: KWin::DrmGpu::testPendingConfiguration(KWin::DrmGpu::TestMode) [clone .constprop.0] (drm_gpu.cpp:403)
>    by 0xCD14B43: KWin::DrmBackend::updateOutputs() (drm_gpu.cpp:309)
>    by 0xCD16F0C: KWin::DrmBackend::handleUdevEvent() (drm_backend.cpp:237)
>    by 0x6FC54F2: UnknownInlinedFun (qobjectdefs_impl.h:398)
>    by 0x6FC54F2: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
>    by 0x6FC88CE: QSocketNotifier::activated(QSocketDescriptor, QSocketNotifier::Type, QSocketNotifier::QPrivateSignal) (moc_qsocketnotifier.cpp:178)
>    by 0x6FC90CA: QSocketNotifier::event(QEvent*) (qsocketnotifier.cpp:302)
>  Uninitialised value was created by a stack allocation
>    at 0xCD329F0: QtPrivate::QSlotObject<bool (KWin::EglGbmBackend::*)(KWin::DrmAbstractOutput*), QtPrivate::List<KWin::DrmAbstractOutput*>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (qobjectdefs_impl.h:411)

Not sure if it tells you what is THE uninitialized object.
Comment 22 Jiri Slaby 2022-02-07 07:27:50 UTC
Finding out the culprit in the == operand:
>   305     const auto &checkBuffer = [this, backend, &buffer](const QSharedPointer<DrmBuffer> &buf){
>   306         const auto &mods = supportedModifiers(buf->format());
>   307         if (backend) {
>   308                 auto fmt1 = buf->format();
>   309                 auto fmt2 = backend->drmFormat(m_output);
>   310                 qDebug() << "fmt1" << fmt1;
>   311                 qDebug() << "fmt2" << fmt2;
>   312                 if (fmt1 == fmt2)
>   313                         if (mods.isEmpty() || mods.contains(buf->modifier()))
>   314                                 if (buf->size() == bufferSize())
>   315                                         buffer = buf;
>   316         }
>   317     };

> by 0x6EA3B87: ~QDebug (qdebug.cpp:154)
> by 0xCD2EC41: KWin::DrmPipeline::checkTestBuffer()::{lambda(QSharedPointer<KWin::DrmBuffer> const&)#1}::operator()(QSharedPointer<KWin::DrmBuffer> const&) const (drm_pipeline.cpp:311)

So it's the pointer returned by backend->drmFormat(m_output);
Comment 23 Vlad Zahorodnii 2022-02-07 10:11:52 UTC
> So it's the pointer returned by backend->drmFormat(m_output);

drmFormat() returns an integer. can you add a default member initializer for GbmFormat::drmFormat, i.e.

struct GbmFormat
{
    uint32_t drmFormat = 0;
Comment 24 Jiri Slaby 2022-02-07 11:51:17 UTC
(In reply to Vlad Zahorodnii from comment #23)
> > So it's the pointer returned by backend->drmFormat(m_output);
> 
> drmFormat() returns an integer. can you add a default member initializer for
> GbmFormat::drmFormat, i.e.
> 
> struct GbmFormat
> {
>     uint32_t drmFormat = 0;

Sure, this makes it go away.
Comment 25 Vlad Zahorodnii 2022-02-07 12:17:58 UTC
Not sure if it's possible but maybe current() returns not a null even though no test frame has been rendered yet.
Comment 26 Jiri Slaby 2022-02-08 06:57:04 UTC
In any way, the original issue is resolved. Let's track the other one in bug 449773.