[Bug 228430] Simple program using QJson* classes segfaults

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Tue May 22 19:16:47 UTC 2018


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=228430

            Bug ID: 228430
           Summary: Simple program using QJson* classes segfaults
           Product: Ports & Packages
           Version: Latest
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: Individual Port(s)
          Assignee: kde at FreeBSD.org
          Reporter: arrowd at FreeBSD.org

Command line to compile:
c++ -I/usr/local/include/qt5/QtCore -I/usr/local/include/qt5 -fPIC
-L/usr/local/lib/qt5 -lQt5Core test.cpp -O0 -g

The problematic code (extracted from KDevelop sources):

#include <QJsonObject>

QJsonObject makeObject()
{
    QJsonObject ret, kplugin;

    kplugin["EnabledByDefault"] = false;
    ret["KPlugin"] = kplugin;

    return ret;
}

int main()
{
    // works
    auto p = makeObject()["KPlugin"].toObject();
    const auto enabledByDefaultValue = p["EnabledByDefault"];

    // segfaults
//     const auto enabledByDefaultValue =
makeObject()["KPlugin"].toObject()["EnabledByDefault"];


    const bool enabledByDefault = enabledByDefaultValue.isNull();
    return 0;
}

Changing clang to g++6 doesn't make segfault go away.
But compiling on FreeBSD 11 or 10 does make it go away.

I've tried using Hex-Rays decompiler to find difference between OK and FAIL
versions. Here is the pseudocode for OK version:

KPluginMetaData::rawData((KPluginMetaData *)&pluginInfoThis);
QString::QString(&string_KPlugin, "KPlugin");
LODWORD(v10) = QJsonObject::operator[](&pluginInfoThis, &string_KPlugin);
v25 = v10;
v26 = v11;
QJsonValueRef::toObject((QJsonValueRef *)&v27);
QString::~QString((QString *)&string_KPlugin);
QJsonObject::~QJsonObject((QJsonObject *)&pluginInfoThis);
QString::QString(&string_EnabledByDef, "EnabledByDefault");
LODWORD(v12) = QJsonObject::operator[](&v27, &string_EnabledByDef);
v21 = v12;
v22 = v13;
QString::~QString((QString *)&string_EnabledByDef);
v16 = 1;
if ( !(QJsonValueRef::isNull((QJsonValueRef *)&v21) & 1) )

Note that before QJsonValueRef::isNull is called, 3 destructors are run:

QString::~QString((QString *)&string_KPlugin);
QJsonObject::~QJsonObject((QJsonObject *)&pluginInfoThis);
QString::~QString((QString *)&string_EnabledByDef);

And here is decompiled code of the FAIL version:

KPluginMetaData::rawData((KPluginMetaData *)&pluginInfoThis);
QString::QString(&string_KPlugin, "KPlugin");
LODWORD(v10) = QJsonObject::operator[](&pluginInfoThis, &string_KPlugin);
v23 = v10;
v24 = v11;
QJsonValueRef::toObject((QJsonValueRef *)&v25);
QString::QString(&string_EnabledByDef, "EnabledByDefault");
LODWORD(v12) = QJsonObject::operator[](&v25, &string_EnabledByDef);
v26 = v12;
v27 = v13;
QString::~QString((QString *)&string_EnabledByDef);
QJsonObject::~QJsonObject((QJsonObject *)&v25);
QString::~QString((QString *)&string_KPlugin);
QJsonObject::~QJsonObject((QJsonObject *)&pluginInfoThis);
v16 = 1;
if ( !(QJsonValueRef::isNull((QJsonValueRef *)&v26) & 1) )

There 4 destructors are run - 3 from above and additional
QJsonObject::~QJsonObject((QJsonObject *)&v25); which is an object that
QJsonObject::operator[](&v25, &string_EnabledByDef); operates on. IIUIC, it
should be OK to call the destructor early, as Qt manages references to object's
data behind the scenes. However, something goes wrong.

CFG's of both cases:
http://arrowd.name/ok.png
http://arrowd.name/fail.png

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the kde-freebsd mailing list