I tried investigating on Debian Bug https://bugs.debian.org/1025104. And I could reproduce it in a i386 and amd64 VM. The crash happens when main is already left and the exit handlers get executed: Thread 1 received signal SIGSEGV, Segmentation fault. 0x00007fd65c0bef73 in KoColorProfileStorage::Private::~Private (this=0x557d2d687090, __in_chrg=<optimized out>) at ./libs/pigment/KoColorProfileStorage.cpp:42 42 delete p; 1: x/i $pc => 0x7fd65c0bef73 <_ZN21KoColorProfileStorage7PrivateD2Ev+787>: call *0x8(%rax) (rr) bt #0 0x00007fd65c0bef73 in KoColorProfileStorage::Private::~Private() (this=0x557d2d687090, __in_chrg=<optimized out>) at ./libs/pigment/KoColorProfileStorage.cpp:42 #1 0x00007fd65c0bcf71 in QScopedPointerDeleter<KoColorProfileStorage::Private>::cleanup(KoColorProfileStorage::Private*) (pointer=0x557d2d687090) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qscopedpointer.h:60 #2 QScopedPointerDeleter<KoColorProfileStorage::Private>::cleanup(KoColorProfileStorage::Private*) (pointer=0x557d2d687090) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qscopedpointer.h:52 #3 QScopedPointer<KoColorProfileStorage::Private, QScopedPointerDeleter<KoColorProfileStorage::Private> >::~QScopedPointer() (this=<optimized out>, __in_chrg=<optimized out>) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qscopedpointer.h:107 #4 KoColorProfileStorage::~KoColorProfileStorage() (this=<optimized out>, __in_chrg=<optimized out>) at ./libs/pigment/KoColorProfileStorage.cpp:56 #5 0x00007fd65c0b531d in KoColorSpaceRegistry::Private::~Private() (this=0x557d2d563d40, __in_chrg=<optimized out>) at ./libs/pigment/KoColorSpaceRegistry.cpp:42 #6 KoColorSpaceRegistry::~KoColorSpaceRegistry() (this=0x7fd65c3841f0 <(anonymous namespace)::Q_QGS_s_instance::innerFunction()::holder>, __in_chrg=<optimized out>) at ./libs/pigment/KoColorSpaceRegistry.cpp:232 #7 0x00007fd65c0b5519 in Holder::~Holder() (this=<optimized out>, __in_chrg=<optimized out>) at ./libs/pigment/KoColorSpaceRegistry.cpp:39 #8 0x00007fd65e2fa435 in __run_exit_handlers (status=0, listp=0x7fd65e48e820 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true, run_dtors=run_dtors@entry=true) at ./stdlib/exit.c:113 #9 0x00007fd65e2fa5aa in __GI_exit (status=<optimized out>) at ./stdlib/exit.c:143 #10 0x00007fd65e2e3191 in __libc_start_call_main (main=main@entry=0x557d2c4544c0 <main(int, char**)>, argc=argc@entry=1, argv=argv@entry=0x7ffdc9b620f8) at ../sysdeps/nptl/libc_start_call_main.h:74 #11 0x00007fd65e2e3245 in __libc_start_main_impl (main=0x557d2c4544c0 <main(int, char**)>, argc=1, argv=0x7ffdc9b620f8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffdc9b620e8) at ../csu/libc-start.c:381 #12 0x0000557d2c458271 in _start () (rr) list 30 ~Private() 31 { 32 Q_FOREACH (KoColorProfile *p, profileMap) { 33 profileUniqueIdMap.remove(p->uniqueId()); 34 delete p; 35 } 36 profileMap.clear(); 37 Q_FOREACH (KoColorProfile *p, profileUniqueIdMap) { 38 delete p; 39 } 40 profileUniqueIdMap.clear(); 41 Q_FOREACH(KoColorProfile *p, duplicates) { 42 delete p; 43 } 44 duplicates.clear(); 45 } Valgrind brought this to the point as double free: ==6079== Invalid read of size 4 ==6079== at 0x7AC33A8: KoColorProfileStorage::Private::~Private() (KoColorProfileStorage.cpp:42) ==6079== by 0x7AC12D2: cleanup (qscopedpointer.h:60) ==6079== by 0x7AC12D2: cleanup (qscopedpointer.h:52) ==6079== by 0x7AC12D2: ~QScopedPointer (qscopedpointer.h:107) ==6079== by 0x7AC12D2: KoColorProfileStorage::~KoColorProfileStorage() (KoColorProfileStorage.cpp:56) ==6079== by 0x7AB8CE6: ~Private (KoColorSpaceRegistry.cpp:42) ==6079== by 0x7AB8CE6: KoColorSpaceRegistry::~KoColorSpaceRegistry() (KoColorSpaceRegistry.cpp:232) ==6079== by 0x7AB8F07: (anonymous namespace)::Q_QGS_s_instance::innerFunction()::Holder::~Holder() (KoColorSpaceRegistry.cpp:39) ==6079== by 0x70D7B5A: __run_exit_handlers (exit.c:89) ==6079== by 0x70D7CB0: exit (exit.c:143) ==6079== by 0x70BF2A0: (below main) (libc_start_call_main.h:74) ==6079== Address 0xdfb8a18 is 0 bytes inside a block of size 8 free'd ==6079== at 0x48436C7: operator delete(void*, unsigned int) (vg_replace_malloc.c:929) ==6079== by 0x7C6A74B: KoDummyColorProfile::~KoDummyColorProfile() (KoDummyColorProfile.cpp:16) ==6079== by 0x7AC314B: KoColorProfileStorage::Private::~Private() (KoColorProfileStorage.cpp:34) ==6079== by 0x7AC12D2: cleanup (qscopedpointer.h:60) ==6079== by 0x7AC12D2: cleanup (qscopedpointer.h:52) ==6079== by 0x7AC12D2: ~QScopedPointer (qscopedpointer.h:107) ==6079== by 0x7AC12D2: KoColorProfileStorage::~KoColorProfileStorage() (KoColorProfileStorage.cpp:56) ==6079== by 0x7AB8CE6: ~Private (KoColorSpaceRegistry.cpp:42) ==6079== by 0x7AB8CE6: KoColorSpaceRegistry::~KoColorSpaceRegistry() (KoColorSpaceRegistry.cpp:232) ==6079== by 0x7AB8F07: (anonymous namespace)::Q_QGS_s_instance::innerFunction()::Holder::~Holder() (KoColorSpaceRegistry.cpp:39) ==6079== by 0x70D7B5A: __run_exit_handlers (exit.c:89) ==6079== by 0x70D7CB0: exit (exit.c:143) ==6079== by 0x70BF2A0: (below main) (libc_start_call_main.h:74) ==6079== Block was alloc'd at ==6079== at 0x4840DDB: operator new(unsigned int) (vg_replace_malloc.c:415) ==6079== by 0x7AB9587: KoColorSpaceRegistry::init() (KoColorSpaceRegistry.cpp:164) ==6079== by 0x7ABA03B: KoColorSpaceRegistry::instance() (KoColorSpaceRegistry.cpp:141) ==6079== by 0x4ED0A94: KisApplication::loadPlugins() (KisApplication.cpp:386) ==6079== by 0x4ED3210: KisApplication::start(KisApplicationArguments const&) (KisApplication.cpp:459) ==6079== by 0x110793: main (main.cc:715) ==6079== And I really found the same pointer 0x557d2d4d7140 being added to the "duplicates" list here: Thread 1 hit Breakpoint 9, QList<KoColorProfile*>::append (this=this@entry=0x557d2d6870a0, t=@0x557d2d4d7298: 0x557d2d4d7140) at /usr/include/c++/12/bits/atomic_base.h:486 486 __glibcxx_assert(__b != memory_order_acq_rel); 1: x/i $pc => 0x7fd65c0afec0 <_ZN5QListIP14KoColorProfileE6appendERKS1_>: push %rbx (rr) bt #0 QList<KoColorProfile*>::append (this=this@entry=0x557d2d6870a0, t=@0x557d2d4d7298: 0x557d2d4d7140) at /usr/include/c++/12/bits/atomic_base.h:486 #1 0x00007fd65c0bd4e9 in KoColorProfileStorage::addProfile (this=0x557d2d563d68, profile=<optimized out>, profile@entry=0x557d2d541be0) at ./libs/pigment/KoColorProfileStorage.cpp:66 #2 0x00007fd65c0b014d in KoColorSpaceRegistry::addProfileToMap (this=this@entry=0x7fd65c3841f0 <(anonymous namespace)::Q_QGS_s_instance::innerFunction()::holder>, p=p@entry=0x557d2d541be0) at ./libs/pigment/KoColorSpaceRegistry.cpp:319 #3 0x00007fd637c7666e in LcmsEnginePlugin::LcmsEnginePlugin (this=0x557d2d51a0a0, parent=<optimized out>) at ./plugins/color/lcms2engine/LcmsEnginePlugin.cpp:138 #4 0x00007fd637c8e549 in KPluginFactory::createInstance<LcmsEnginePlugin, QObject> (parentWidget=<optimized out>, parent=<optimized out>, args=QList<QVariant> (size = 0)) at /usr/include/KF5/KCoreAddons/kpluginfactory.h:891 #5 0x00007fd65c729343 in KPluginFactory::create(char const*, QWidget*, QObject*, QList<QVariant> const&, QString const&) () from /lib/x86_64-linux-gnu/libKF5CoreAddons.so.5 #6 0x00007fd65c7880ed in KPluginFactory::create<QObject> (args=..., parent=<optimized out>, this=<optimized out>) at /usr/include/KF5/KCoreAddons/kpluginfactory.h:939 #7 KoPluginLoader::load (this=this@entry=0x7fd65c79c5c0 <(anonymous namespace)::Q_QGS_pluginLoaderInstance::innerFunction()::holder>, serviceType="Krita/ColorSpace", versionString="[X-Pigment-PluginVersion] == 28", config=..., owner=owner@entry=0x0, cache=cache@entry=true) at ./libs/koplugin/KoPluginLoader.cpp:128 #8 0x00007fd65c0b5f9d in KoColorSpaceRegistry::init (this=0x7fd65c3841f0 <(anonymous namespace)::Q_QGS_s_instance::innerFunction()::holder>) at ./libs/pigment/KoColorSpaceRegistry.cpp:187 #9 0x00007fd65c0b6592 in KoColorSpaceRegistry::instance () at ./libs/pigment/KoColorSpaceRegistry.cpp:39 #10 0x00007fd65f2b9123 in KisApplication::loadPlugins (this=<optimized out>) at ./libs/ui/KisApplication.cpp:386 #11 0x00007fd65f2bb8f6 in KisApplication::start (this=this@entry=0x7ffdc9b61f00, args=...) at ./libs/ui/KisApplication.cpp:459 #12 0x0000557d2c456e31 in main (argc=<optimized out>, argv=<optimized out>) at ./krita/main.cc:715 (rr) finish Run till exit from #0 QList<KoColorProfile*>::append (this=this@entry=0x557d2d6870a0, t=@0x557d2d4d7298: 0x557d2d4d7140) at /usr/include/c++/12/bits/atomic_base.h:486 KoColorProfileStorage::addProfile (this=0x557d2d563d68, profile=<optimized out>, profile@entry=0x557d2d541be0) at ./libs/pigment/KoColorProfileStorage.cpp:66 66 d->duplicates.append(d->profileUniqueIdMap[profile->uniqueId()]); 1: x/i $pc => 0x7fd65c0bd4e9 <_ZN21KoColorProfileStorage10addProfileEP14KoColorProfile+681>: mov 0x70(%rsp),%rdi (rr) print d->profileMap Could not find operator->. (rr) print d.d->profileMap $2 = QHash<QString, KoColorProfile *> (size = 10) = { ["scRGB (linear)"] = 0x557d2d7a8990, ["Artifex Software sGray ICC Profile"] = 0x557d2d7d4b60, ["Artifex Software sRGB ICC Profile"] = 0x557d2d53f9e0, ["Artifex CMYK SWOP Profile"] = 0x557d2d512a70, ["Artifex Software esRGB ICCProfile"] = 0x557d2d541b60, ["default"] = 0x557d2d4d7140, ["Chemical proof"] = 0x557d2d6fe5d0, ["High Dynamic Range UHDTV Wide Color Gamut Display (Rec. 2020) - SMPTE ST 2084 PQ EOTF"] = 0x557d2d783ab0, ["Artifex PS CMYK Profile"] = 0x557d2d541be0, ["Artifex Software A98 ICC Profile "] = 0x557d2dbc4f50 } (rr) print d.d->duplicates $3 = QList<KoColorProfile *> (size = 1) = { [0] = 0x557d2d4d7140 } Therefore it gets once freed in KoColorProfileStorage::Private::~Private the first loop over "profileMap". And then it crashes when it tries to free it a second time in the third loop over "duplicates". I assume this is related to this commit: https://invent.kde.org/graphics/krita/-/commit/ee16f1366178213cb0543003da86baab7b52fb65 Maybe removing in the first loop the deleted pointers also from the "duplicates" list could solve this issue? Like in following untested modification? --- krita-5.1.3+dfsg.orig/libs/pigment/KoColorProfileStorage.cpp +++ krita-5.1.3+dfsg/libs/pigment/KoColorProfileStorage.cpp @@ -31,10 +31,12 @@ struct KoColorProfileStorage::Private { { Q_FOREACH (KoColorProfile *p, profileMap) { profileUniqueIdMap.remove(p->uniqueId()); + duplicates.removeAll(p); delete p; } profileMap.clear(); Q_FOREACH (KoColorProfile *p, profileUniqueIdMap) { + duplicates.removeAll(p); delete p; } profileUniqueIdMap.clear(); Krita Version: 5.1.3 Hidpi: true Qt Version (compiled): 5.15.6 Version (loaded): 5.15.6 OS Information Build ABI: x86_64-little_endian-lp64 Build CPU: x86_64 CPU: x86_64 Kernel Type: linux Kernel Version: 6.0.0-5-amd64 Pretty Productname: Debian GNU/Linux bookworm/sid Product Type: debian Product Version: unknown Desktop:
Overnight a local Debian package built of 5.1.3 finished with my mentioned change, and this one does really no longer crashes. For some reason also this night, the Debian Maintainer uploaded a new version 5.1.4, which states to fix this bug, too. This is really the case in my test environment. I failed to add in my previous information the output to stdout, especially important because of the "Duplicated profile" messages in 5.1.3, which are no longer visible with this new 5.1.4. 5.1.3: $ krita $ krita Lcms2 error: 13 LUT is not suitable to be saved as LutBToA Lcms2 error: 7 Couldn't write type 'mBA ' Lcms2 error: 13 LUT is not suitable to be saved as LutBToA Lcms2 error: 7 Couldn't write type 'mBA ' krita.lib.pigment: Duplicated profile "Artifex PS CMYK Profile" "/usr/share/color/icc/ghostscript/gray_to_k.icc" "" Lcms2 error: 13 LUT is not suitable to be saved as LutBToA Lcms2 error: 7 Couldn't write type 'mBA ' Lcms2 error: 13 LUT is not suitable to be saved as LutBToA Lcms2 error: 7 Couldn't write type 'mBA ' Lcms2 error: 13 LUT is not suitable to be saved as LutBToA Lcms2 error: 7 Couldn't write type 'mBA ' Lcms2 error: 13 LUT is not suitable to be saved as LutBToA Lcms2 error: 7 Couldn't write type 'mBA ' krita.lib.pigment: Duplicated profile "Artifex PS CMYK Profile" "/usr/share/color/icc/ghostscript/ps_cmyk.icc" "/usr/share/color/icc/ghostscript/gray_to_k.icc" Lcms2 error: 13 LUT is not suitable to be saved as LutBToA Lcms2 error: 7 Couldn't write type 'mBA ' Lcms2 error: 13 LUT is not suitable to be saved as LutBToA Lcms2 error: 7 Couldn't write type 'mBA ' krita.lib.pigment: Duplicated profile "Artifex Software sRGB ICC Profile" "/usr/share/color/icc/ghostscript/srgb.icc" "/usr/share/color/icc/ghostscript/default_rgb.icc" krita.lib.pigment: Replacing color space factory "LABA" "L*a*b*/Alpha (16-bit integer/channel)" with "LABA" "L*a*b* (16-bit integer/channel, unmanaged)" krita.lib.pigment: Replacing color space factory "RGBA" "RGB/Alpha (8-bit integer/channel)" with "RGBA" "RGB (8-bit integer/channel, unmanaged)" krita.lib.pigment: Replacing color space factory "RGBA16" "RGB/Alpha (16-bit integer/channel)" with "RGBA16" "RGB (16-bit integer/channel, unmanaged)" QObject::startTimer: Timers cannot have negative intervals /usr/lib/x86_64-linux-gnu/krita-python-libs/krita added to PYTHONPATH Lcms2 error: 13 LUT is not suitable to be saved as LutBToA Lcms2 error: 7 Couldn't write type 'mBA ' 19 -- exe=/usr/bin/krita 14 -- appname=krita 17 -- apppath=/usr/bin 10 -- signal=11 10 -- pid=42710 12 -- startupid=0 KCrash: crashing... crashRecursionCounter = 2 ... $ 5.1.4: $ krita QObject::startTimer: Timers cannot have negative intervals /usr/lib/x86_64-linux-gnu/krita-python-libs/krita added to PYTHONPATH $
Git commit 145176d25a0425346820d86d14388633e3d58f40 by L. E. Segovia. Committed on 22/12/2022 at 20:17. Pushed by lsegovia into branch 'master'. KoColorProfileStorage: fix possible crash on exit M +2 -0 libs/pigment/KoColorProfileStorage.cpp https://invent.kde.org/graphics/krita/commit/145176d25a0425346820d86d14388633e3d58f40