Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

qt.core.qobject.connect: QObject::connect(Quotient::Connection, DevicesModel): invalid nullptr parameter and Segmentation fault in libQuotient when opening "Device"-settings in NeoChat. #828

Closed
dreirund opened this issue Nov 11, 2024 · 16 comments
Labels
crash A crash occurs in the library code invalid There's nothing to improve in the library

Comments

@dreirund
Copy link

dreirund commented Nov 11, 2024

Ahoj,

this was reported initially for NeoChat (↗ here), but ↗ over there I was told that it is a libQuotient issue.

So I recompiled libQuotient with debugging information and report it here.

Since I am not a coder and not a code-understander, I still refer to the symptoms as I see them in NeoChat, so I still refer to NeoChat. I include a GDB backtrace where NeoChat and libQuotient are compiled with debugging information.


Describe the bug

When in NeoChat I enter Settings -> "Device", it crashes with qt.core.qobject.connect: QObject::connect(Quotient::Connection, DevicesModel): invalid nullptr parameter and Segmentation fault.

To Reproduce

Steps to reproduce the behaviour, and the description of the actual result:

  1. Be on my system, Artix GNU/Linux (rolling release), so software pretty much up to date.
  2. Compile libQuotient git checkout from this repo; git commit hash: 294d8a5
  3. Compile NeoChat from it's git repository, git commit hash: 19e8cd5e4.
  4. Start neochat.
  5. After logging in, open settings and open the "Device" tab.
  6. Observe a crash with qt.core.qobject.connect: QObject::connect(Quotient::Connection, DevicesModel): invalid nullptr parameter and Segmentation fault.

I attach terminal output and GDB log below under "Additional context".

Expected behavior

Beeing able to access and edit "Device" settings.

Is it environment-specific?

I do not know.

But here are environment information:

  • OS: Artix GNU/Linux (rolling release)
  • Version of the library: 0.9.0, git checkout at commit hash g294d8a57
  • Linkage: dynamic

Additional context

  • Last lines of the terminal output leading to the crash:
    [...]
    qrc:/qt/qml/org/kde/neochat/login/Loading.qml:26: TypeError: Cannot read property 'closeDialog' of null
    [New Thread 0x7fff7aa006c0 (LWP 20456)]
    [New Thread 0x7fff620006c0 (LWP 20457)]
    [New Thread 0x7fff616006c0 (LWP 20458)]
    [Thread 0x7fff616006c0 (LWP 20458) exited]
    [Thread 0x7fff620006c0 (LWP 20457) exited]
    [Thread 0x7fff7aa006c0 (LWP 20456) exited]
    [New Thread 0x7fff7aa006c0 (LWP 20459)]
    [New Thread 0x7fff620006c0 (LWP 20460)]
    [New Thread 0x7fff616006c0 (LWP 20461)]
    [New Thread 0x7fff60c006c0 (LWP 20462)]
    qt.core.qobject.connect: QObject::connect(Quotient::Connection, DevicesModel): invalid nullptr parameter
    qrc:/qt/qml/org/kde/kirigami/dialogs/Dialog.qml:344:18: QML ScrollView: Binding loop detected for property "calculatedImplicitHeight":
    qrc:/qt/qml/org/kde/kirigami/dialogs/Dialog.qml:361:9
    qrc:/qt/qml/org/kde/kirigami/dialogs/Dialog.qml:401:33: QML Binding: Binding loop detected for property "value":
    qrc:/qt/qml/org/kde/kirigami/dialogs/Dialog.qml:409:13
    
    Thread 1 "neochat" received signal SIGSEGV, Segmentation fault.
    0x00007ffff4a2be15 in QString::append(QString const&) () from /usr/lib/libQt6Core.so.6
    
  • GDB backtrace after the crash:
    #0  0x00007ffff4a2be15 in QString::append(QString const&) () at /usr/lib/libQt6Core.so.6
    #1  0x00007ffff6864b9c in QString::operator+= (this=0x7fffffffc4e0, s=...) at /usr/include/qt6/QtCore/qstring.h:542
    #2  operator+ (lhs=..., rhs=...) at /usr/include/qt6/QtCore/qstring.h:1428
    #3  Quotient::Database::database (this=this@entry=0x0) at /usr/src/debug/libquotient-debug-git/libquotient-git/Quotient/database.cpp:433
    #4  0x00007ffff6864ce4 in Quotient::Database::prepareQuery (this=this@entry=0x0, queryString=...) at /usr/src/debug/libquotient-debug-git/libquotient-git/Quotient/database.cpp:438
    #5  0x00007ffff67604e7 in Quotient::Connection::isKnownE2eeCapableDevice (this=this@entry=0x55555686d4d0, userId=..., deviceId=...)
        at /usr/src/debug/libquotient-debug-git/libquotient-git/Quotient/connection.cpp:1884
    #6  0x000055555590e537 in DevicesModel::data (this=this@entry=0x555557345270, index=..., role=role@entry=5) at /usr/src/debug/neochat-debug-git/neochat/src/models/devicesmodel.cpp:78
    #7  0x0000555555917576 in DevicesProxyModel::filterAcceptsRow (this=0x555557350390, source_row=<optimized out>, source_parent=<optimized out>)
        at /usr/src/debug/neochat-debug-git/neochat/src/models/devicesproxymodel.cpp:20
    #8  0x00007ffff4b80a08 in ??? () at /usr/lib/libQt6Core.so.6
    #9  0x00007ffff4b82547 in ??? () at /usr/lib/libQt6Core.so.6
    #10 0x00007ffff4b8a54e in QSortFilterProxyModel::rowCount(QModelIndex const&) const () at /usr/lib/libQt6Core.so.6
    #11 0x00007ffff479a249 in VDMAbstractItemModelDataType::rowCount (this=<optimized out>, model=<optimized out>)
        at /usr/src/debug/qt6-declarative/qtdeclarative/src/qmlmodels/qqmldmabstractitemmodeldata_p.h:228
    #12 0x00007ffff4799e55 in QQmlAdaptorModel::rowCount (this=this@entry=0x55555c51f9c0) at /usr/src/debug/qt6-declarative/qtdeclarative/src/qmlmodels/qqmladaptormodel.cpp:83
    #13 0x00007ffff47b5a26 in QQmlDelegateModelPrivate::adaptorModelCount (this=0x55555c51f930) at /usr/src/debug/qt6-declarative/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp:196
    #14 QQmlDelegateModel::handleModelReset (this=0x555557351360) at /usr/src/debug/qt6-declarative/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp:1928
    #15 0x00007ffff49add9a in ??? () at /usr/lib/libQt6Core.so.6
    #16 0x00007ffff4b58585 in QAbstractItemModel::endResetModel() () at /usr/lib/libQt6Core.so.6
    #17 0x00007ffff4b8d3d6 in ??? () at /usr/lib/libQt6Core.so.6
    #18 0x00007ffff49add9a in ??? () at /usr/lib/libQt6Core.so.6
    #19 0x00007ffff4b58585 in QAbstractItemModel::endResetModel() () at /usr/lib/libQt6Core.so.6
    #20 0x00005555559125d8 in operator() (__closure=<optimized out>) at /usr/src/debug/neochat-debug-git/neochat/src/models/devicesmodel.cpp:41
    #21 operator() (__closure=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:141
    #22 QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, DevicesModel::fetchDevices()::<lambda()> >::call(DevicesModel::fetchDevices()::<lambda()>&, void**)::<lambda()> > (args=<optimized out>, fn=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:65
    #23 QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, DevicesModel::fetchDevices()::<lambda()> >::call (f=<optimized out>, arg=<optimized out>)
        at /usr/include/qt6/QtCore/qobjectdefs_impl.h:140
    #24 QtPrivate::FunctorCallable<DevicesModel::fetchDevices()::<lambda()> >::call<QtPrivate::List<>, void> (f=<optimized out>, arg=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:362
    #25 QtPrivate::QCallableObject<DevicesModel::fetchDevices()::<lambda()>, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *)
        (which=<optimized out>, this_=<optimized out>, r=<optimized out>, a=<optimized out>, ret=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:572
    #26 0x00007ffff49add9a in ??? () at /usr/lib/libQt6Core.so.6
    #27 0x00007ffff6743426 in Quotient::BaseJob::success (this=<optimized out>, _t1=<optimized out>) at /usr/src/debug/libquotient-debug-git/build/QuotientQt6_autogen/T4CFEN5LXH/moc_basejob.cpp:537
    #28 0x00007ffff685be36 in Quotient::BaseJob::finishJob (this=0x55555740daa0) at /usr/src/debug/libquotient-debug-git/libquotient-git/Quotient/jobs/basejob.cpp:631
    #29 0x00007ffff49add9a in ??? () at /usr/lib/libQt6Core.so.6
    #30 0x00007ffff499f5b7 in QObject::event(QEvent*) () at /usr/lib/libQt6Core.so.6
    #31 0x00007ffff5afe0b7 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/libQt6Widgets.so.6
    #32 0x00007ffff4955f08 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/libQt6Core.so.6
    #33 0x00007ffff495697c in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () at /usr/lib/libQt6Core.so.6
    #34 0x00007ffff4bb3f54 in ??? () at /usr/lib/libQt6Core.so.6
    #35 0x00007ffff230aeb9 in ??? () at /usr/lib/libglib-2.0.so.0
    #36 0x00007ffff236b5d7 in ??? () at /usr/lib/libglib-2.0.so.0
    #37 0x00007ffff230a432 in g_main_context_iteration () at /usr/lib/libglib-2.0.so.0
    #38 0x00007ffff4bb1358 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/libQt6Core.so.6
    #39 0x00007ffff4961a55 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/libQt6Core.so.6
    #40 0x00007ffff495723a in QCoreApplication::exec() () at /usr/lib/libQt6Core.so.6
    #41 0x00005555555da3b6 in main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/neochat-debug-git/neochat/src/main.cpp:307
    
  • Full terminal output in a run under GDB (so, combined terminal output of NeoChat and GDB output):
    neochat-libquotient-debug-gdb-log.log.
@dreirund dreirund changed the title Segmentation Fault in libQuotient when opening "Device"-settings in NeoChat. invalid nullptr parameter. qt.core.qobject.connect: QObject::connect(Quotient::Connection, DevicesModel): invalid nullptr parameter and Segmentation fault in libQuotient when opening "Device"-settings in NeoChat. Nov 11, 2024
@KitsuneRal
Copy link
Member

The libQuotient frames in the stack trace don't look healthy indeed. Thanks for reporting it here.

@KitsuneRal KitsuneRal added the crash A crash occurs in the library code label Nov 11, 2024
@KitsuneRal KitsuneRal moved this to In work in libQuotient 1 Nov 11, 2024
@TobiasFella
Copy link
Member

I have looked at this at some point and it looks like the database isn't initialized for some reason. FWIW, all of this code is going away / changing entirely soon, so there's not really a point in debugging this further

@KitsuneRal
Copy link
Member

Actually, I'm not really sure it's libQuotient's fault, now that I looked at the code. Looks like NeoChat tries to call an E2EE-related method without checking if E2EE is even enabled on an account, or before it's enabled.

@dreirund
Copy link
Author

I'm not really sure it's libQuotient's fault, now that I looked at the code. Looks like NeoChat […]

↗ People at NeoChat tell otherwise:

I have written that; there's nothing for NeoChat to do since the problem is on libQuotient's side

Can you please step in there and discuss? I do not understand the code.

@dreirund
Copy link
Author

Looks like NeoChat tries to call an E2EE-related method without checking if E2EE is even enabled on an account, or before it's enabled.

I use end to end encryption on my account. (Maybe not (yet) with NeoChat, but in general.)

@KitsuneRal
Copy link
Member

I'm not really sure it's libQuotient's fault, now that I looked at the code. Looks like NeoChat […]

↗ People at NeoChat tell otherwise:

I know - Tobias is here, and my comment was mainly for him. What he wrote here is also true, though.

@KitsuneRal
Copy link
Member

Just one more idea - @dreirund, can you check what the terminal output has regarding keychain? You can literally search for the keyword if your terminal allows it or if you save the output to a file.

@KitsuneRal
Copy link
Member

KitsuneRal commented Nov 11, 2024

Actually, I already see it in the Neochat issue. You don't seem to have the org.freedesktop.secrets DBus service in order. If the library cannot write the database encryption key to the keychain it disables E2EE to avoid the existing database corruption.

@dreirund
Copy link
Author

dreirund commented Nov 11, 2024 via email

@KitsuneRal
Copy link
Member

KitsuneRal commented Nov 11, 2024

Problem is, you cannot type an encryption key by hand, it's impractical. You can store it in pass; but unfortunately, Qt Keychain doesn't know how to work with it... And yes, the right thing for the client would be to issue an early warning that E2EE cannot be turned on, instead of crashing. But I don't see how the library (being totally offscreen) can help with that - clients can already check with the library API whether E2EE is actually usable. I'll drop the message to that effect on the NeoChat side, too (once I set up an account in KDE Bugzilla...)

@dreirund
Copy link
Author

dreirund commented Nov 11, 2024 via email

@KitsuneRal
Copy link
Member

Qt Keychain tries several options - I don't remember the exact logic but it can connect to gnome-keyring, KDE's kwallet, and libsecret, the latter being effectively a frontend to access whatever provides org.freedesktop.secrets DBus API.

Without a desktop environment, I'd say gnome-keyring is the easiest (and probably the most lightweight) to setup. Quotient's own CI pipeline has the bare minimal initialisation of gnome-keyring-daemon that is sufficient to test the library. I wouldn't probably advise using an empty password, and maybe you would prefer to ask for a password interactively (gnome-keyring can do it for you). And you can manage the entries in gnome-keyring using a separate application, Seahorse.

@dreirund
Copy link
Author

dreirund commented Nov 12, 2024 via email

@dreirund
Copy link
Author

dreirund commented Nov 12, 2024

Thanks; I installed gnome-keyring now and that at least hides the bug.

I still get crashes.

Now I added a new account, clicked a bit in the settings, and a segmentation fault again.
It happened twice, each time after logging in with a new account and going "somewhere" (I do not remember exactly where first and in which order) into the settings just after logging in with the new account.

GDB backtrace:

#0  0x00007ffff4bad9ef in ??? () at /usr/lib/libQt6Core.so.6
#1  0x000055555578493e in NeoChatConnection::errorOccured (this=this@entry=0x0, _t1=...) at /usr/src/debug/neochat-debug-git/build/src/neochat_autogen/include/moc_neochatconnection.cpp:689
#2  0x000055555591af40 in operator() (__closure=0x555556cca4e0, error=...) at /usr/src/debug/neochat-debug-git/neochat/src/login.cpp:88
#3  operator() (__closure=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:141
#4  QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1, 2, 3>, QtPrivate::List<QString, QString, int, int>, void, LoginHelper::init()::<lambda(QString, const QString&, int, int)> >::call(LoginHelper::init()::<lambda(QString, const QString&, int, int)>&, void**)::<lambda()> > (args=<optimized out>, fn=<optimized out>)
    at /usr/include/qt6/QtCore/qobjectdefs_impl.h:65
#5  QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1, 2, 3>, QtPrivate::List<QString, QString, int, int>, void, LoginHelper::init()::<lambda(QString, const QString&, int, int)> >::call
    (f=..., arg=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:140
#6  QtPrivate::FunctorCallable<LoginHelper::init()::<lambda(QString, const QString&, int, int)>, QString, QString, int, int>::call<QtPrivate::List<QString, QString, int, int>, void>
    (f=..., arg=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:362
#7  QtPrivate::QCallableObject<LoginHelper::init()::<lambda(QString, const QString&, int, int)>, QtPrivate::List<QString, QString, int, int>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *) (which=<optimized out>, this_=0x555556cca4d0, r=<optimized out>, a=<optimized out>, ret=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:572
#8  0x00007ffff4badd9a in ??? () at /usr/lib/libQt6Core.so.6
#9  0x00007ffff6b5bcf9 in Quotient::Connection::networkError (this=this@entry=0x555556cb7400, _t1=..., _t2=..., _t3=<optimized out>, _t3@entry=1, _t4=<optimized out>, _t4@entry=0)
    at /usr/src/debug/libquotient-debug-git/build/QuotientQt6_autogen/include/moc_connection.cpp:1829
#10 0x00007ffff6b5f833 in operator() (__closure=<optimized out>, retriesTaken=1, nextInMilliseconds=0) at /usr/src/debug/libquotient-debug-git/libquotient-git/Quotient/connection.cpp:455
#11 operator() (__closure=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:141
#12 QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1>, QtPrivate::List<int, long int>, void, Quotient::Connection::sync(int)::<lambda(int, int)> >::call(Quotient::Connection::sync(int)::<lambda(int, int)>&, void**)::<lambda()> > (args=<optimized out>, fn=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:65
#13 QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1>, QtPrivate::List<int, long int>, void, Quotient::Connection::sync(int)::<lambda(int, int)> >::call (f=<optimized out>, arg=<optimized out>)
    at /usr/include/qt6/QtCore/qobjectdefs_impl.h:140
#14 QtPrivate::FunctorCallable<Quotient::Connection::sync(int)::<lambda(int, int)>, int, long int>::call<QtPrivate::List<int, long>, void> (f=<optimized out>, arg=<optimized out>)
    at /usr/include/qt6/QtCore/qobjectdefs_impl.h:362
#15 QtPrivate::QCallableObject<Quotient::Connection::sync(int)::<lambda(int, int)>, QtPrivate::List<int, long int>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *)
    (which=<optimized out>, this_=<optimized out>, r=<optimized out>, a=<optimized out>, ret=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:572
#16 0x00007ffff4badd9a in ??? () at /usr/lib/libQt6Core.so.6
#17 0x00007ffff6b43349 in Quotient::BaseJob::retryScheduled (this=<optimized out>, _t1=<optimized out>, _t2=<optimized out>)
    at /usr/src/debug/libquotient-debug-git/build/QuotientQt6_autogen/T4CFEN5LXH/moc_basejob.cpp:510
#18 0x00007ffff4badd9a in ??? () at /usr/lib/libQt6Core.so.6
#19 0x00007ffff4bb6f44 in QTimer::timerEvent(QTimerEvent*) () at /usr/lib/libQt6Core.so.6
#20 0x00007ffff4b9f569 in QObject::event(QEvent*) () at /usr/lib/libQt6Core.so.6
#21 0x00007ffff5cfe0b7 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/libQt6Widgets.so.6
#22 0x00007ffff4b55f08 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/libQt6Core.so.6
#23 0x00007ffff4ccaba9 in QTimerInfoList::activateTimers() () at /usr/lib/libQt6Core.so.6
#24 0x00007ffff4db3edc in ??? () at /usr/lib/libQt6Core.so.6
#25 0x00007ffff250aeb9 in ??? () at /usr/lib/libglib-2.0.so.0
#26 0x00007ffff256b5d7 in ??? () at /usr/lib/libglib-2.0.so.0
#27 0x00007ffff250a432 in g_main_context_iteration () at /usr/lib/libglib-2.0.so.0
#28 0x00007ffff4db1358 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/libQt6Core.so.6
#29 0x00007ffff4b61a55 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/libQt6Core.so.6
#30 0x00007ffff4b5723a in QCoreApplication::exec() () at /usr/lib/libQt6Core.so.6
#31 0x00005555555da3b6 in main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/neochat-debug-git/neochat/src/main.cpp:307

Full terminal output of running neochat within gdb attached: neochat.gdb.log

@KitsuneRal
Copy link
Member

Glad that the original issue was resolved. This new stacktrace is concerned with something else; and it clearly points at the NeoChat codebase, so please direct this to the NeoChat issue tracker.

@github-project-automation github-project-automation bot moved this from In work to 0.9 - Done in libQuotient 1 Nov 16, 2024
@KitsuneRal KitsuneRal added the invalid There's nothing to improve in the library label Nov 16, 2024
@dreirund
Copy link
Author

This new stacktrace is concerned with something else; and it clearly points at the NeoChat codebase, so please direct this to the NeoChat issue tracker.

↗ Here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
crash A crash occurs in the library code invalid There's nothing to improve in the library
Projects
None yet
Development

No branches or pull requests

3 participants