https://bugs.kde.org/show_bug.cgi?id=472862
--- Comment #14 from Harald Sitter <sit...@kde.org> --- I've found a way to make plasma crash like this: - open krunner kcm - enable kate session (this creates a kdirwatch) - disable kate session (this deletes the kdirwatch) - open kate and save a session - crash What appears to happen for plasma is incredibly stupid but at first glance hard to solve. KRunner (the framework) gives every runner a thread, it does this by creating the runner on the current thread and then moveToThread()s it to the target thread. Inside the konsoleprofile and katesession runner implementations we create a KDirWatch. Now because of how kdirwatch works things get complicated. Multiple "fronting" kdirwatch objects may point to the same internal private instance that actually encapsulates the watching logic. This is so we can install 300 kdirwatches on plasmarc but in the end only a single inotify watch is used to back all those fronting objects. Things fall over because the backing objects are managed thread-local e.g. if I have two threads and each have watches on plasmarc it in fact uses two private instances and two inotify instances (one per thread). This then gets in the way of moveToThread because moving a KDirWatch from thread0 to thread1 means a KDirWatch living in thread1 now points to a KDirWatchPrivate instance in thread0. Specifically the crash appears because of use-after-destruction... The destructor has a check for dwp_self.hasLocalData() (that's the thread-local backing data) https://invent.kde.org/frameworks/kcoreaddons/-/blob/80b6893d85bc90fb5d82882c41caa171748c1c63/src/lib/io/kdirwatch.cpp#L1895 this will evaluate to false because we never constructed a private on this thread (the private is on the original thread) https://invent.kde.org/frameworks/kcoreaddons/-/blob/80b6893d85bc90fb5d82882c41caa171748c1c63/src/lib/io/kdirwatch.cpp#L85 this then means the refcount on thread0 is off because we don't unref in the destructor and the end result is that we have a "Client" record that points to an instance (that is the pubic KDirWatch) that no longer exists https://invent.kde.org/frameworks/kcoreaddons/-/blob/80b6893d85bc90fb5d82882c41caa171748c1c63/src/lib/io/kdirwatch.cpp#L1401 and there is our crash. When the thread-local private in thread0 now receives an event pertaining to the since-deleted KDirWatch that was moved to thread1 it will crash on a bogus pointer. Supposedly we could just change the if in the destructor to always unref when there is a d regardless of thread-local data. I currently cannot conceive of a scenario where unrefing should be skipped when a d is available. Mind you, I don't understand how kwin_wayland would end up in that particular hell, as I can only see it using KDirWatch::self which shouldn't have this problem. -- You are receiving this mail because: You are watching all bug changes.