Bug 474556

Summary: Crash in ViewerWindow::showInlineMessage() when stopping recording with Webm
Product: [Applications] Spectacle Reporter: Nate Graham <nate>
Component: GeneralAssignee: Noah Davis <noahadvs>
Status: RESOLVED DUPLICATE    
Severity: crash CC: el, kde, kde
Priority: NOR Keywords: qt6
Version: git-master   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: New crash information added by DrKonqi

Description Nate Graham 2023-09-15 14:38:55 UTC
100% of the time when I stop a screen recording using either the Webm or MP4 file formats, Spectacle crashes in ViewerWindow::showSavedVideoMessage().

This is a different crash from the one in Bug 467966.

Application: Spectacle (spectacle), signal: Segmentation fault
Content of s_kcrashErrorMessage: std::unique_ptr<char []> = {get() = 0x0}
[KCrash Handler]
#5  0x00007fd936cdb5f4 in QQuickView::rootObject() const () at /lib64/libQt6Quick.so.6
#6  0x00000000004633f8 in ViewerWindow::showInlineMessage(QString const&, QMap<QString, QVariant> const&) (this=this@entry=0x0, qmlFile=..., properties=...) at /home/nate/kde/src/spectacle/src/Gui/ViewerWindow.cpp:137
#7  0x000000000046429e in ViewerWindow::showSavedVideoMessage(QUrl const&) (this=0x0, messageArgument=...) at /home/nate/kde/src/spectacle/src/Gui/ViewerWindow.cpp:152
#8  0x00000000004489c0 in operator() (path=<optimized out>, __closure=0x194a790) at /home/nate/kde/src/spectacle/src/SpectacleCore.cpp:248
#9  QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<const QString&>, void, SpectacleCore::SpectacleCore(QObject*)::<lambda(const QString&)> >::call (arg=<optimized out>, f=...) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:127
#10 QtPrivate::Functor<SpectacleCore::SpectacleCore(QObject*)::<lambda(const QString&)>, 1>::call<QtPrivate::List<QString const&>, void> (arg=<optimized out>, f=...) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:241
#11 QtPrivate::QFunctorSlotObject<SpectacleCore::SpectacleCore(QObject*)::<lambda(const QString&)>, 1, QtPrivate::List<const QString&>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *) (which=<optimized out>, this_=0x194a780, r=<optimized out>, a=<optimized out>, ret=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:409
#12 0x00007fd9351de394 in void doActivate<false>(QObject*, int, void**) () at /lib64/libQt6Core.so.6
#13 0x0000000000484433 in VideoPlatform::recordingSaved(QString const&) (this=this@entry=0x7fd91400cc70, _t1=...) at /home/nate/kde/build6/spectacle/src/spectacle_autogen/include/moc_VideoPlatform.cpp:320
#14 0x0000000000484e69 in operator() (__closure=0x21dda50) at /home/nate/kde/src/spectacle/src/Platforms/VideoPlatformWayland.cpp:54
#15 QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, VideoPlatformWayland::startRecording(const QString&, VideoPlatform::RecordingMode, const VideoPlatform::RecordingOption&, bool)::<lambda()> >::call (arg=<optimized out>, f=...) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:127
#16 QtPrivate::Functor<VideoPlatformWayland::startRecording(const QString&, VideoPlatform::RecordingMode, const VideoPlatform::RecordingOption&, bool)::<lambda()>, 0>::call<QtPrivate::List<>, void> (arg=<optimized out>, f=...) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:241
#17 QtPrivate::QFunctorSlotObject<VideoPlatformWayland::startRecording(const QString&, VideoPlatform::RecordingMode, const VideoPlatform::RecordingOption&, bool)::<lambda()>, 0, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *) (which=<optimized out>, this_=0x21dda40, r=<optimized out>, a=<optimized out>, ret=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:409
#18 0x00007fd9351de394 in void doActivate<false>(QObject*, int, void**) () at /lib64/libQt6Core.so.6
#19 0x00007fd9389bd96e in PipeWireBaseEncodedStream::setActive(bool) (this=0x176f970, active=false) at /home/nate/kde/src/kpipewire/src/pipewirebaseencodedstream.cpp:119
#20 0x000000000044f800 in SpectacleCore::qt_metacall(QMetaObject::Call, int, void**) (this=0x7ffc78f36ff0, _c=QMetaObject::InvokeMetaMethod, _id=21, _a=0x7ffc78f33b70) at /home/nate/kde/build6/spectacle/src/spectacle_autogen/include/moc_SpectacleCore.cpp:622
#21 0x00007fd9367bc14a in QQmlObjectOrGadget::metacall(QMetaObject::Call, int, void**) const () at /lib64/libQt6Qml.so.6
#22 0x00007fd936660657 in QV4::CallPrecise(QQmlObjectOrGadget const&, QQmlPropertyData const&, QV4::ExecutionEngine*, QV4::CallData*, QMetaObject::Call) () at /lib64/libQt6Qml.so.6
#23 0x00007fd936662e25 in QV4::QObjectMethod::callInternal(QV4::Value const*, QV4::Value const*, int) const () at /lib64/libQt6Qml.so.6
#24 0x00007fd9366bbbbb in QV4::Moth::VME::interpret(QV4::JSTypesStackFrame*, QV4::ExecutionEngine*, char const*) () at /lib64/libQt6Qml.so.6
#25 0x00007fd9366c0787 in QV4::Moth::VME::exec(QV4::JSTypesStackFrame*, QV4::ExecutionEngine*) () at /lib64/libQt6Qml.so.6
#26 0x00007fd93660adc6 in QV4::doCall(QV4::Function*, QV4::Value const*, QV4::Value const*, int, QV4::ExecutionContext*) () at /lib64/libQt6Qml.so.6
#27 0x00007fd93660b3cb in QV4::Function::call(QObject*, void**, QMetaType const*, int, QV4::ExecutionContext*) () at /lib64/libQt6Qml.so.6
#28 0x00007fd93677faf7 in QQmlJavaScriptExpression::evaluate(void**, QMetaType const*, int) () at /lib64/libQt6Qml.so.6
#29 0x00007fd936713beb in QQmlBoundSignalExpression::evaluate(void**) () at /lib64/libQt6Qml.so.6
#30 0x00007fd9367145d0 in QQmlBoundSignal_callback(QQmlNotifierEndpoint*, void**) () at /lib64/libQt6Qml.so.6
#31 0x00007fd9367aacfc in QQmlNotifier::emitNotify(QQmlNotifierEndpoint*, void**) () at /lib64/libQt6Qml.so.6
#32 0x00007fd9351de000 in void doActivate<false>(QObject*, int, void**) () at /lib64/libQt6Core.so.6
#33 0x00007fd9372f183a in QQuickAbstractButtonPrivate::handleRelease(QPointF const&, unsigned long) () at /lib64/libQt6QuickTemplates2.so.6
#34 0x00007fd937318ac5 in QQuickControl::mouseReleaseEvent(QMouseEvent*) () at /lib64/libQt6QuickTemplates2.so.6
#35 0x00007fd936c3b2b8 in QQuickItem::event(QEvent*) () at /lib64/libQt6Quick.so.6
#36 0x00007fd9377c0af8 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /lib64/libQt6Widgets.so.6
#37 0x00007fd93517cdb8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /lib64/libQt6Core.so.6
#38 0x00007fd936dcd44d in QQuickDeliveryAgentPrivate::deliverMatchingPointsToItem(QQuickItem*, bool, QPointerEvent*, bool) () at /lib64/libQt6Quick.so.6
#39 0x00007fd936dcdba7 in QQuickDeliveryAgentPrivate::deliverUpdatedPoints(QPointerEvent*) () at /lib64/libQt6Quick.so.6
#40 0x00007fd936dcef33 in QQuickDeliveryAgentPrivate::deliverPointerEvent(QPointerEvent*) () at /lib64/libQt6Quick.so.6
#41 0x00007fd936dcff8b in QQuickDeliveryAgentPrivate::handleMouseEvent(QMouseEvent*) () at /lib64/libQt6Quick.so.6
#42 0x00007fd936dd1ee8 in QQuickDeliveryAgent::event(QEvent*) () at /lib64/libQt6Quick.so.6
#43 0x00007fd936ce7572 in QQuickWindow::event(QEvent*) () at /lib64/libQt6Quick.so.6
#44 0x00007fd9377c0af8 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /lib64/libQt6Widgets.so.6
#45 0x00007fd93517cdb8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /lib64/libQt6Core.so.6
#46 0x00007fd935a09ad7 in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) () at /lib64/libQt6Gui.so.6
#47 0x00007fd935a63aac in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib64/libQt6Gui.so.6
#48 0x00007fd935f40534 in userEventSourceDispatch(_GSource*, int (*)(void*), void*) () at /lib64/libQt6Gui.so.6
#49 0x00007fd932d134fc in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
#50 0x00007fd932d716b8 in g_main_context_iterate.isra () at /lib64/libglib-2.0.so.0
#51 0x00007fd932d10b83 in g_main_context_iteration () at /lib64/libglib-2.0.so.0
#52 0x00007fd935420951 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib64/libQt6Core.so.6
#53 0x00007fd9351899f3 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib64/libQt6Core.so.6
#54 0x00007fd93518569d in QCoreApplication::exec() () at /lib64/libQt6Core.so.6
#55 0x0000000000425207 in main(int, char**) (argc=<optimized out>, argv=<optimized out>) at /home/nate/kde/src/spectacle/src/Main.cpp:137
[Inferior 1 (process 614523) detached]
Comment 1 Noah Davis 2023-09-16 02:26:32 UTC
I see this bug report is for 23.04.1. Do you have the same bug with git master?
Comment 2 Nate Graham 2023-09-16 03:16:35 UTC
It was indeed with git master, sorry.
Comment 3 Noah Davis 2023-09-18 17:41:55 UTC
Could you tell me exactly what you're doing and what settings related to saving videos you have? I am unable to reproduce the crash.
Comment 4 David Edmundson 2023-09-29 13:55:21 UTC
>#5  0x00007fd936cdb5f4 in QQuickView::rootObject() const () at /lib64/libQt6Quick.so.6

This is typically a sign that QML failed to load, hence no root object.
This could mean a missing import on the user. In either case spectacle should report any QML errors to stderr and exit gracefully.
Comment 5 Noah Davis 2023-10-02 20:10:56 UTC
(In reply to David Edmundson from comment #4)
> >#5  0x00007fd936cdb5f4 in QQuickView::rootObject() const () at /lib64/libQt6Quick.so.6
> 
> This is typically a sign that QML failed to load, hence no root object.
> This could mean a missing import on the user. In either case spectacle
> should report any QML errors to stderr and exit gracefully.

That was one of my first thoughts, but I asked Nate to put a Q_ASSERT(rootObject() != nullptr) there and he said it didn't trigger.
Comment 6 David Edmundson 2023-10-13 13:49:39 UTC
I should have read this:

#7  0x000000000046429e in ViewerWindow::showSavedVideoMessage(QUrl const&) (this=0x0, messageArgument=...) at /home/nate/kde/src/spectacle/src/Gui/ViewerWindow.cpp:152

this=0

ViewerWindow is not instantiated. The lifespan is managed by something else and there's effectively a weakpointer for the singleton. 

    connect(m_videoPlatform.get(), &VideoPlatform::recordingSaved, this, [this](const QString &path) {
        const QUrl url = QUrl::fromUserInput(path, {}, QUrl::AssumeLocalFile);
        ViewerWindow::instance()->showSavedVideoMessage(url);

and several other places are not guarding ViewerWindow::instance().

It should be either guarded or we should figure the lifespan
Comment 7 Noah Davis 2023-10-13 14:23:19 UTC
(In reply to David Edmundson from comment #6)
> I should have read this:
> 
> #7  0x000000000046429e in ViewerWindow::showSavedVideoMessage(QUrl const&)
> (this=0x0, messageArgument=...) at
> /home/nate/kde/src/spectacle/src/Gui/ViewerWindow.cpp:152
> 
> this=0
> 
> ViewerWindow is not instantiated. The lifespan is managed by something else
> and there's effectively a weakpointer for the singleton. 
> 
>     connect(m_videoPlatform.get(), &VideoPlatform::recordingSaved, this,
> [this](const QString &path) {
>         const QUrl url = QUrl::fromUserInput(path, {},
> QUrl::AssumeLocalFile);
>         ViewerWindow::instance()->showSavedVideoMessage(url);
> 
> and several other places are not guarding ViewerWindow::instance().
> 
> It should be either guarded or we should figure the lifespan

What's really weird about this is that it should currently be impossible to activate this code in a situation where the ViewerWindow is null. You can currently only start and stop recording while a ViewerWindow is open.
Comment 8 Bug Janitor Service 2023-10-27 12:40:50 UTC
A possibly relevant merge request was started @ https://invent.kde.org/graphics/spectacle/-/merge_requests/279
Comment 9 Nate Graham 2023-11-06 17:03:09 UTC
Fixed with the commits in https://invent.kde.org/graphics/spectacle/-/merge_requests/283.
Comment 10 Nate Graham 2024-02-15 18:14:12 UTC

*** This bug has been marked as a duplicate of bug 469336 ***
Comment 11 Ellie 2024-04-17 16:45:18 UTC
Created attachment 168624 [details]
New crash information added by DrKonqi

spectacle (23.08.4) using Qt 5.15.12

I was clicking "finish recording", it was a recoding of a specific window and fairly short.

-- Backtrace (Reduced):
#4  0x00007f1a9710b0c0 in QQuickView::rootObject() const () at /lib64/libQt5Quick.so.5
#5  0x000056429ac886dd in ViewerWindow::showInlineMessage(QString const&, QMap<QString, QVariant> const&) (this=0x0, qmlFile=..., properties=...) at /usr/src/debug/spectacle-23.08.4/src/Gui/ViewerWindow.cpp:146
#6  0x000056429ac78985 in ViewerWindow::showSavedVideoMessage(QUrl const&) (messageArgument=..., this=0x0) at /usr/src/debug/spectacle-23.08.4/src/Gui/ViewerWindow.cpp:161
#7  operator() (path=<optimized out>, __closure=0x56429ca1f110) at /usr/src/debug/spectacle-23.08.4/src/SpectacleCore.cpp:233
#10 QtPrivate::QFunctorSlotObject<SpectacleCore::SpectacleCore(QObject*)::<lambda(const QString&)>, 1, QtPrivate::List<const QString&>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *) (which=<optimized out>, this_=0x56429ca1f100, r=<optimized out>, a=<optimized out>, ret=<optimized out>) at /usr/include/qt5/QtCore/qobjectdefs_impl.h:443