mozilla-vpn-client
mozilla-vpn-client copied to clipboard
mozillavpn crashes (core dumped) when starting UI
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
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.
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.
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
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:
- The module
Qt5Compat.GraphicalEffects
fails to load (though thelibQt6Core5Compat6
package is installed)- Fixed by additionally installing
qt6-qt5compat-imports
(could you try this @mcorino? Otherwise report what’s in~/.local/share/mozillavpn.txt
?)
- Fixed by additionally installing
- 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 incommandui.cpp
:
I get the following output:// 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;
About to load main.qml Loaded (?) main.qml Aborted (core dumped)
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.
➤ Sarah Bird commented:
Santiago Andrigo marking this as enhancement as it’s effectively a request to support a new flavor of linux.
➤ Andrea Marchesini commented:
I assign this bug to me even if the PR was written by a contributor.
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?
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.