semlanik/qtprotobuf

Accessing Messages Qproperties from Qml cause GUI app to crash

Opened this issue · 4 comments

  • When accessing a Qtprotobuf message non trivial QProperty ( shared or list of shared pointer to object ), QML JS engine takes ownership of the object pointed to which get destroyed as soon as the QML call returns. The shared pointers ref count gets corrupted and causes a crash following any atomic access to the object by any owning shared pointer.

A fix would be to set the object’s ownership to cpp in the QProperty accessor or in the type registration.

@Rightbputnow1 Another way to completely sidestep those issues is to transform the message classes into reference counted objects, much like QString and QByteArray #180

@Rightbputnow1 could you please provide the minimum example when this happens. In common cases you don't need to set an explicit value ownership when accessing the property. But of course there are exceptions, e.g. when the value is returned from the function. Also it's not clear to me what corrupts the shared pointer ref counter.

RBQt commented

Say you have the following sample message:

syntax="proto3";

package Crash;

message Sample {
repeated Agregate agregate = 1;
}

message Agregate {
uint64 sample = 1;
}
Now agregate is generated as QList<QSharedPointer>

Accessing any QSharedPointer's data in the previous list from Qml trough a Q_INVOKABLE would blindside the QSharedPointer atomic ref count as the QML JS engine would take ownership of the data and destroy it as soon as the Q_INVOKABLE call return since its note referenced by any javascript named id. The QSharedPointer is now left with a floating data although indicating otherwise and would cause any further dereferencing of the QSharedPointer data to randomly crash the app (garbage collector behavior is not predictible, may instantly crash giving insight on the source of the crash, may crash further in the app's lifetime leaving the user clueless which happened to my colleagues :').

Best fix would be to implement a QML friendly cpp ownership enforcing QSharedPointer that does not hang its data to dry once accessed from the QML.
Quickest fix has been proposed as a pull request, basically adding the cpp ownership setter in the message generation portion of code of the message generator.