[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#623492: plasma-desktop segfaults, prevents all (?) other kde apps from loading

reassign 623492 kdebase-workspace-bin

KDE maintainers bcc'd, please see the bug for further context.

On Thu, 21 Apr 2011 at 11:42:55 +0100, Simon McVittie wrote:
> This indicates a bug in whatever's using libdbus (looks like QtDBus, or
> something higher up the stack), which wasn't previously detected by libdbus:
> the caller is trying to send a boolean value that isn't either 0 or 1. We
> fixed that (among other undiagnosed invalid messages) in 1.4.8.

I got plasma-desktop working in a VM, and have found one instance of this bug;
if I make libdbus warnings fatal and log in to a KDE session, I get one
abort. I'm on a train with no KDE debug symbols, but I think I may have
found what caused it:

smcv@klavier:~$ gdb /usr/bin/kded4 core 
#27 0xb3e84a1f in PowerDevilDaemon::stateChanged(int, bool) ()
   from /usr/lib/kde4/kded_powerdevil.so

I think this is a bug in PowerDevilDaemon.cpp; I've seen a similar bug in
another C++ project that uses D-Bus. In PowerDevilDaemon::Private we see:

    explicit Private()
            : notifier(Solid::Control::PowerManager::notifier())
            , currentConfig(0)
            , status(PowerDevilDaemon::NoAction)
            , ckSessionInterface(0) {}

This doesn't initialize all the members of Private. Most are harmless,
because "clever" types like QString have a default constructor which the
compiler will call. However, simple numeric types don't have a default
constructor, so this leaves batteryPercent, brightness, isPlugged and
ckAvailable uninitialized, and in particular, the two booleans can take
numeric values other than 0 or 1 (bool is at least 1 byte long, and
uninitialized memory can contain any bit pattern).

It seems PowerDevilDaemon doesn't have any particular guarantee whether
setACPlugged will be called before the first emission of stateChanged; if it
isn't, the first emission will have garbage in its boolean argument. I think
this is what's happened here.

Worse, the compiler is allowed to optimize operations on bool variables
by assuming they take value 0 or 1, so changing the stateChanged emission
to have argument !!d->isPlugged wouldn't work either - the compiler would
optimize away the double-negation. (I've seen this happen "in real life",
in the other project I mentioned.)

When I moved /usr/lib/kde4/kded_powerdevil.so into /root, logged in to a KDE
session and logged out again, I didn't see any more libdbus warnings in
.xsession-errors, and didn't get another coredump.

I believe the solution is to initialize all the members of Private
properly, but I don't have the bandwidth to download the source code at the
moment, so I haven't tried it.


Reply to: