mozilla-vpn-client icon indicating copy to clipboard operation
mozilla-vpn-client copied to clipboard

mozillavpn crashes (core dumped) when starting UI

Open mcorino opened this issue 2 years ago • 5 comments

Description I managed to build mozillavpn on OpenSuSE Leap 15.4 without errors as far as I can tell and it works just fine as long as I stick to the commandline commands. Installation went fine and the mozillavpn.service runs ok. When I attempt to start the UI though the app crashes with an abort message.

Technical Information Platform: OpenSuSE Leap 15.4 (with Qt 6.3.0 installed) FX product: Mozilla VPN 2.8.4

Steps to Reproduce

Turn on the computer Click on the VPN menu item to open the app or use command line 'ui' command to start it, both fail.

Actual Results When starting from the commandline the app terminates with the message "Aborted (core dumped)".

Journalctl shows:

Jun 13 19:51:18 mco-desktop.m2c-software.nl kernel: Code: ab f4 ff 48 8b 04 24 48 85 c0 74 07 8b 10 83 fa 01 7e 12 31 c9 31 d2 31 f6 4c 89 e7 e8 6c de fb ff 48 8b 04 24 48 8b 54 24 08 <4c> 8b 22 48 85 c0 74 06 f0 83 28 01 74 25 4d 85 e4 74 > Jun 13 19:51:18 mco-desktop.m2c-software.nl kernel: mozillavpn[10802]: segfault at 0 ip 00000000004e12bd sp 00007fff3d2aa850 error 4 in mozillavpn[400000+5a6000] Jun 13 19:51:18 mco-desktop.m2c-software.nl mozillavpn[10768]: [13.06.2022 19:51:18.471] Debug: (linux - DBusService) Version request Jun 13 19:51:18 mco-desktop.m2c-software.nl systemd[1546]: Started MozillaVPN. Jun 13 19:51:17 mco-desktop.m2c-software.nl plasmashell[1757]: file:///usr/share/plasma/plasmoids/org.kde.plasma.kicker/contents/ui/RunnerResultsList.qml:50:9: Unable to assign [undefined] to int Jun 13 19:51:17 mco-desktop.m2c-software.nl plasmashell[1757]: file:///usr/share/plasma/plasmoids/org.kde.plasma.kicker/contents/ui/RunnerResultsList.qml:50:9: Unable to assign [undefined] to int Jun 13 19:51:17 mco-desktop.m2c-software.nl plasmashell[1757]: file:///usr/share/plasma/plasmoids/org.kde.plasma.kicker/contents/ui/RunnerResultsList.qml:50:9: Unable to assign [undefined] to int

Expected Results The VPN should launch/open.

┆Issue is synchronized with this Jira Bug

mcorino avatar Jun 13 '22 18:06 mcorino

Hi mcorino. Thanks for your report.

At the moment, unfortunately, OpenSuse is not a supported platform.

We have lots of linux users on the team, including myself, so we understand how frustrating a response this is.

We are not closing this ticket, we're just unlikely to get round to debugging this in the near future.

Based on your report it's probably something to do with Qt6. I recently found that I was able to build the vpn (on ubuntu) with no errors but then had runtime failures.

We have a separate ticket open here: https://github.com/mozilla-mobile/mozilla-vpn-client/issues/3730 to improve the readme and build instructions. The last comment from me describes what I had to do to get things working. I don't know how far this will get you on OpenSuse but would love to hear back from you if you're able to get any further.

birdsarah avatar Jun 16 '22 17:06 birdsarah

Thanks for the reply.

As far as I can determine I have all the right (equivalent) packages installed (I checked several from control.qt6 list in detail) and as said I did not see any compile errors (only a small number of non-threatening warnings).

Can you elaborate about the dbus problems you mentioned in your comment. As the journalctl log shows the crash directly following a "Debug: (linux - DBusService) Version request" this might be relevant.

mcorino avatar Jun 16 '22 17:06 mcorino

I’m running into the same issue − segfault on UI start − when building the 2.9.0 release with Qt6, on OpenSUSE Tumbleweed.

I seem to always have a 1 or 2 threads in runtime.futexsleep, and the segfaulted thread with the following backtrace:

Stack trace of thread 27640:
#0  0x000000000050a158 QmlEngineHolder::window() const (mozillavpn + 0x10a158)
#1  0x000000000052dfdd SystemTrayNotificationHandler::SystemTrayNotificationHandler(QObject*) (mozillavpn + 0x12dfdd)
#2  0x000000000053bd76 LinuxSystemTrayNotificationHandler::LinuxSystemTrayNotificationHandler(QObject*) (mozillavpn + 0x13bd76)
#3  0x000000000050684a NotificationHandler::create(QObject*) (mozillavpn + 0x10684a)
#4  0x000000000048b1ab CommandUI::run(QList<QString>&)::{lambda()#1}::operator()() const (mozillavpn + 0x8b1ab)
#5  0x000000000047f577 std::function<int ()>::operator()() const (mozillavpn + 0x7f577)
#6  0x0000000000488c3c CommandUI::run(QList<QString>&) (mozillavpn + 0x88c3c)
#7  0x0000000000481132 CommandLineParser::parse(int, char**) (mozillavpn + 0x81132)
#8  0x0000000000440290 main (mozillavpn + 0x40290)
#9  0x00007fc2722ab5b0 __libc_start_call_main (libc.so.6 + 0x405b0)
#10 0x00007fc2722ab679 __libc_start_main_impl (libc.so.6 + 0x40679)
#11 0x0000000000443355 _start (mozillavpn + 0x43355)

$_siginfo is telling me the segfault is due to dereferencing a NULL pointer, but I don’t know if that’s 100% to be trusted. Nevertheless it’s the window() call on this line:

https://github.com/mozilla-mobile/mozilla-vpn-client/blob/3ae9aea3c262c0aa7a8d313976f80f38dcc957e5/src/systemtraynotificationhandler.cpp#L79-L80

Disassembly and registers on the 2 last frames seem to confirm we’re dereferencing a NULL pointer, though it’s a little unclear whether that’s the return value of QmlEngineHolder::instance() or of QArrayDataPointer<QObject*>::reallocateAndGrow(…)

See gdb output of inspecting core dump.
(gdb) up
#1  0x000000000052dfdd in SystemTrayNotificationHandler::SystemTrayNotificationHandler (this=this@entry=0x7fc220011210, parent=parent@entry=0x19a4c90) at /builddir/build/BUILD/mozillavpn-2.9.0/src/systemtraynotificationhandler.cpp:79
79      /builddir/build/BUILD/mozillavpn-2.9.0/src/systemtraynotificationhandler.cpp: Directory not empty.
(gdb) x/6i 0x52dfd0
   0x52dfd0 <SystemTrayNotificationHandler::SystemTrayNotificationHandler(QObject*)+2128>:      call   0x50a100 <QmlEngineHolder::instance()>
   0x52dfd5 <SystemTrayNotificationHandler::SystemTrayNotificationHandler(QObject*)+2133>:      mov    %rax,%rdi
   0x52dfd8 <SystemTrayNotificationHandler::SystemTrayNotificationHandler(QObject*)+2136>:      call   0x50a120 <QmlEngineHolder::window() const>
=> 0x52dfdd <SystemTrayNotificationHandler::SystemTrayNotificationHandler(QObject*)+2141>:      mov    $0x20,%edi
   0x52dfe2 <SystemTrayNotificationHandler::SystemTrayNotificationHandler(QObject*)+2146>:      mov    %rax,%r13
   0x52dfe5 <SystemTrayNotificationHandler::SystemTrayNotificationHandler(QObject*)+2149>:      movq   $0x424130,-0xa0(%rbp)
(gdb) down
#0  0x000000000050a158 in QmlEngineHolder::window (this=<optimized out>) at /usr/include/qt6/QtCore/qlist.h:159
159             inline constexpr explicit iterator(T *n) : i(n) {}
(gdb) x/20i QmlEngineHolder::window
   0x50a120 <QmlEngineHolder::window() const>:           push   %rbx
   0x50a121 <QmlEngineHolder::window() const+1>:         lea    0x18(%rdi),%rsi
   0x50a125 <QmlEngineHolder::window() const+5>:         sub    $0x20,%rsp
   0x50a129 <QmlEngineHolder::window() const+9>:         mov    %rsp,%rdi
   0x50a12c <QmlEngineHolder::window() const+12>:        call   0x422750 <QQmlApplicationEngine::rootObjects() const@plt>
   0x50a131 <QmlEngineHolder::window() const+17>:        mov    (%rsp),%rax
   0x50a135 <QmlEngineHolder::window() const+21>:        test   %rax,%rax
   0x50a138 <QmlEngineHolder::window() const+24>:        je     0x50a141 <QmlEngineHolder::window() const+33>
   0x50a13a <QmlEngineHolder::window() const+26>:        mov    (%rax),%edx
   0x50a13c <QmlEngineHolder::window() const+28>:        cmp    $0x1,%edx
   0x50a13f <QmlEngineHolder::window() const+31>:        jle    0x50a153 <QmlEngineHolder::window() const+51>
   0x50a141 <QmlEngineHolder::window() const+33>:        xor    %ecx,%ecx
   0x50a143 <QmlEngineHolder::window() const+35>:        xor    %edx,%edx
   0x50a145 <QmlEngineHolder::window() const+37>:        xor    %esi,%esi
   0x50a147 <QmlEngineHolder::window() const+39>:        mov    %rsp,%rdi
   0x50a14a <QmlEngineHolder::window() const+42>:        call   0x4b45f0 <QArrayDataPointer<QObject*>::reallocateAndGrow(QArrayData::GrowthPosition, long long, QArrayDataPointer<QObject*>*)>
   0x50a14f <QmlEngineHolder::window() const+47>:        mov    (%rsp),%rax
   0x50a153 <QmlEngineHolder::window() const+51>:        mov    0x8(%rsp),%rdx
=> 0x50a158 <QmlEngineHolder::window() const+56>:        mov    (%rdx),%rbx
   0x50a15b <QmlEngineHolder::window() const+59>:        test   %rax,%rax
(gdb) info registers
rax            0x0                 0
rbx            0x7fc220011210      140471737324048
rcx            0x0                 0
rdx            0x0                 0
rsi            0x0                 0
rdi            0x0                 0
rbp            0x7fff54641470      0x7fff54641470
rsp            0x7fff54641240      0x7fff54641240
r8             0x1                 1
r9             0x7fc274434f00      140473150951168
r10            0x1f50b70           32836464
r11            0xd78db72022f82d71  -2914472035185316495
r12            0x7fc220011288      140471737324168
r13            0x7fff54641860      140734609234016
r14            0x1fae1b0           33218992
r15            0x1f1d2a0           32625312
rip            0x50a158            0x50a158 <QmlEngineHolder::window() const+56>
eflags         0x10202             [ IF RF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0

Cimbali avatar Aug 01 '22 17:08 Cimbali

A lot of debugging info

After rebuilding in debug mode and downloading all Qt6 debug symbols, it seems that QmlEngineHolder::window() happily takes the first value in the list of it’s m_engine->rootObjects() list. However this list appears to be empty and uninitialised:

(gdb) frame 9
#9  QList<QObject*>::first (this=0x7fffffffc2e0) at /usr/include/qt6/QtCore/qlist.h:643
643         inline T& first() { Q_ASSERT(!isEmpty()); return *begin(); }
(gdb) p *this
$3 = {<QListSpecialMethods<QObject*>> = {<QListSpecialMethodsBase<QObject*>> = {<No data fields>}, <No data fields>}, d = {d = 0x0, ptr = 0x0, size = 0}}

In debug mode, the !isEmpty() assert inside first() (seen above) fails, called from here:

https://github.com/mozilla-mobile/mozilla-vpn-client/blob/77ad158acef4b1fb174de4252b0b95f1e18c1992/src/qmlengineholder.cpp#L52-L55


After deeper inspection, it seems something in engine->load(main.qml) is not going as expected:

https://github.com/mozilla-mobile/mozilla-vpn-client/blob/b1096046edebac992bdf76e194e1abfc65473c13/src/commands/commandui.cpp#L555-L568

The NotificationHandler gets created before the callback is called. MozillaVPN::mainWindowLoaded() does not get called either.


By the way I haven’t for the life of me been able to find where any of the logger.level() << … output goes. It’s not /var/log/mozillavpn.txt though it exists. After modifying the LogHandler to output everything to stderr, I’ve managed to find the errors:

[01.08.2022 21:36:21.484] Warning: QQmlApplicationEngine failed to load component
[01.08.2022 21:36:21.484] Warning: qrc:/ui/main.qml:110:5: Type VPNWasmHeader unavailable (main.qml:110)
[01.08.2022 21:36:21.484] Warning: qrc:/nebula/components/VPNWasmHeader.qml:57:9: Type VPNLinearGradient unavailable (VPNWasmHeader.qml:57)
[01.08.2022 21:36:21.484] Warning: qrc:/nebula/compat/VPNLinearGradient.qml:6:1: module "Qt5Compat.GraphicalEffects" is not installed (VPNLinearGradient.qml:6)

[01.08.2022 21:36:21.490] Error: ASSERT: "!isEmpty()" in file /usr/include/qt6/QtCore/qlist.h, line 643 (qlist.h:643)

So we have 2 errors:

  1. The module Qt5Compat.GraphicalEffects fails to load (though the libQt6Core5Compat6 package is installed)
    • Fixed by additionally installing qt6-qt5compat-imports (could you try this @mcorino? Otherwise report what’s in ~/.local/share/mozillavpn.txt?)
  2. The QQmlApplicationEngine::objectCreated callback seems to not exit properly when the QML fails to load. That’s what causes the segfault and is an error handling issue in the code @birdsarah. In fact after some testing it seems the callback is not called at all, contrary to what the documentation says.
    With the following prints in commandui.cpp:
     // Here is the main QML file.
     const QUrl url(QStringLiteral("qrc:/ui/main.qml"));
     QObject::connect(
         engine, &QQmlApplicationEngine::objectCreated, qApp,
         [url](QObject* obj, const QUrl& objUrl) {
           if (!obj && url == objUrl) {
             std::cerr << "Failed to load main.qml" << std::endl;
             QGuiApplication::exit(-1);
           } else {
             std::cerr << "MANAGED to load main.qml" << std::endl;
           }
         },
         Qt::QueuedConnection);
     std::cerr << "About to load main.qml" << std::endl;
     engine->load(url);
     std::cerr << "Loaded (?) main.qml" << std::endl;
    
    I get the following output:
    About to load main.qml
    Loaded (?) main.qml
    Aborted (core dumped)
    

Cimbali avatar Aug 01 '22 19:08 Cimbali

I think the queued signal and QGuiApplication::exit only happen in the main loop, i.e. once qApp->exec() is called. However the window is needed before that, while the initialisation is still going on.

Cimbali avatar Aug 01 '22 21:08 Cimbali

➤ Sarah Bird commented:

Santiago Andrigo marking this as enhancement as it’s effectively a request to support a new flavor of linux.

data-sync-user avatar Apr 10 '23 17:04 data-sync-user

➤ Andrea Marchesini commented:

I assign this bug to me even if the PR was written by a contributor.

data-sync-user avatar Apr 10 '23 17:04 data-sync-user

This issue reported a crash when a runtime dependency was missing. I think this is reproducible on any platform where users build from source.

This now marks “support opensuse” as completed, but to clarify, opensuse is still not a supported platform? Or is it?

Cimbali avatar Apr 11 '23 08:04 Cimbali

For what it’s worth the support page for Mozilla VPN on Linux still says:

Note: Mozilla VPN is available for:

  • Ubuntu 18.04 LTS (Bionic Beaver)
  • Ubuntu 20.04 LTS (Focal Fossa)
  • Ubuntu 22.04 LTS (Jammy Jellyfish)

[…]

Other Linux distributions

So far, we do not offer packages for any other Linux distributions.

Cimbali avatar Apr 11 '23 11:04 Cimbali