Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-105958

[Android] Intent + Talkback leads to deadlock

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 6.3.1
    • None
    • Android
    • b832a5ac7 (dev), 5aca4e09e (tqtc/lts-5.15), 126fe788e (6.3), 58e54dcfd (6.5), 5be8837e2 (6.4), 2e46273e2 (tqtc/lts-6.2)

    Description

      Returning to a running Qt Android app via Intent while TalkBack is active leads sometimes to a deadlock. It occurs always for me when using a debugger. As far as I can analyze it the following occurs:

      1. The App gets woken up by an Intent. A QWindowSystemInterfacePrivate::ApplicationStateChanged event gets processed. This processing ends in QSGThreadedRenderLoop::polishAndSync(), blocking the qtMainLoopThread #1 with a mutex until the QML rendering thread returns (I assume it is a rendering thread, it has no name). The QML rendering thread #2 tries to create a surface in QAndroidPlatformOpenGLWindow::eglSurface() by calling QtAndroid::createSurface() and blocks in a mutex until the call to the Android API returns.
      2. In parallel TalkBack tries to get information about the window and calls e.g. androidjniaccessiblity.cpp::descriptionForAccessibleObject() on the Android thread #3. The needed information are gathered from objects living in the main thread #1. Therefor QMetaObject::invokeMethod(_, _, Qt::BlockingQueuedConnection, _) gets called, resulting in a blocked thread waiting on the qtMainLoopThread.

      We therefor get a deadlock. I naively tried to add AndroidDeadlockProtector to androidjniaccessiblity.cpp::runInObjectContext, but without luck.

      #1 qtMainLoopThread

      syscall 0x00000000f31faa1c
      __futex_wait_ex(void volatile*, bool, int, bool, timespec const*) 0x00000000f31ffc7e
      pthread_cond_wait 0x00000000f3247952
      QWaitConditionPrivate::wait(QDeadlineTimer) qwaitcondition_unix.cpp:147
      QWaitCondition::wait(QMutex*, QDeadlineTimer) qwaitcondition_unix.cpp:220
      QSGThreadedRenderLoop::polishAndSync(QSGThreadedRenderLoop::Window*, bool) qsgthreadedrenderloop.cpp:1555
      QSGThreadedRenderLoop::handleExposure(QQuickWindow*) qsgthreadedrenderloop.cpp:1312
      QSGThreadedRenderLoop::exposureChanged(QQuickWindow*) qsgthreadedrenderloop.cpp:1232
      QQuickWindow::exposeEvent(QExposeEvent*) qquickwindow.cpp:214
      QWindow::event(QEvent*) qwindow.cpp:2508
      QQuickWindow::event(QEvent*) qquickwindow.cpp:1580
      QCoreApplicationPrivate::notify_helper(QObject*, QEvent*) qcoreapplication.cpp:1234
      doNotify(QObject*, QEvent*) qcoreapplication.cpp:1163
      QCoreApplication::notify(QObject*, QEvent*) qcoreapplication.cpp:1146
      QGuiApplication::notify(QObject*, QEvent*) qguiapplication.cpp:1955
      QCoreApplication::notifyInternal2(QObject*, QEvent*) qcoreapplication.cpp:1067
      QCoreApplication::sendSpontaneousEvent(QObject*, QEvent*) qcoreapplication.cpp:1497
      QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent*) qguiapplication.cpp:3197
      QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) qguiapplication.cpp:2094
      QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) qwindowsysteminterface.cpp:1137
      QWindowSystemInterface::flushWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) qwindowsysteminterface.cpp:1106
      QAndroidPlatformWindow::applicationStateChanged(Qt::ApplicationState) qandroidplatformwindow.cpp:205
      QAndroidPlatformOpenGLWindow::applicationStateChanged(Qt::ApplicationState) qandroidplatformopenglwindow.cpp:163
      QAndroidPlatformScreen::applicationStateChanged(Qt::ApplicationState) qandroidplatformscreen.cpp:352
      QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<Qt::ApplicationState>, void, void (QAndroidPlatformScreen::)(Qt::ApplicationState)>::call(void (QAndroidPlatformScreen::)(Qt::ApplicationState), QAndroidPlatformScreen*, void**) qobjectdefs_impl.h:171
      void QtPrivate::FunctionPointer<void (QAndroidPlatformScreen::)(Qt::ApplicationState)>::call<QtPrivate::List<Qt::ApplicationState>, void>(void (QAndroidPlatformScreen::)(Qt::ApplicationState), QAndroidPlatformScreen*, void**) qobjectdefs_impl.h:208
      QtPrivate::QSlotObject<void (QAndroidPlatformScreen::)(Qt::ApplicationState), QtPrivate::List<Qt::ApplicationState>, void>::impl(int, QtPrivate::QSlotObjectBase, QObject*, void*, bool) qobjectdefs_impl.h:419
      QtPrivate::QSlotObjectBase::call(QObject*, void**) qobjectdefs_impl.h:399
      void doActivate<false>(QObject*, int, void**) qobject.cpp:3921
      QMetaObject::activate(QObject*, QMetaObject const*, int, void**) qobject.cpp:3981
      QGuiApplication::applicationStateChanged(Qt::ApplicationState) moc_qguiapplication.cpp:416
      QGuiApplicationPrivate::setApplicationState(Qt::ApplicationState, bool) qguiapplication.cpp:3735
      QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) qguiapplication.cpp:2060
      QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) qwindowsysteminterface.cpp:1137
      QUnixEventDispatcherQPA::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) qunixeventdispatcher.cpp:64
      QAndroidEventDispatcher::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) qandroideventdispatcher.cpp:99
      QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) qeventloop.cpp:136
      QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) qeventloop.cpp:218
      QCoreApplication::exec() qcoreapplication.cpp:1388
      QGuiApplication::exec() qguiapplication.cpp:1887
      exec(QScopedPointer<QCoreApplication, QScopedPointerDeleter<QCoreApplication> > const&) Bootstrap.cpp:125
      governikus::initApp(int&, char**) Bootstrap.cpp:176
      main main.cpp:90
      startQtApplication(_JNIEnv*, _jclass*) androidjnimain.cpp:565
      art_quick_generic_jni_trampoline 0x00000000ef7620de
      art_quick_invoke_stub_internal 0x00000000ef75d5d6
      art_quick_invoke_static_stub 0x00000000efb7d610
      art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*) 0x00000000ef7b68fc
      art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*) 0x00000000ef8ced26
      bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x00000000ef8c7158
      void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*) 0x00000000ef76b0b0
      ExecuteSwitchImplAsm 0x00000000ef762c76
      art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.16561771350904891617) 0x00000000ef8c03c0
      art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*) 0x00000000ef8c697e
      bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x00000000ef8c713e
      void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*) 0x00000000ef769732
      ExecuteSwitchImplAsm 0x00000000ef762c76
      art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.16561771350904891617) 0x00000000ef8c03c0
      art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*) 0x00000000ef8c697e
      bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x00000000ef8c713e
      void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*) 0x00000000ef769732
      ExecuteSwitchImplAsm 0x00000000ef762c76
      art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.16561771350904891617) 0x00000000ef8c03c0
      art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*) 0x00000000ef8c68ba
      artQuickToInterpreterBridge 0x00000000efb6040a
      art_quick_to_interpreter_bridge 0x00000000ef762164
      art_quick_invoke_stub_internal 0x00000000ef75d5d6
      art_quick_invoke_stub 0x00000000efb7d4e0
      art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*) 0x00000000ef7b68ea
      art::JValue art::InvokeVirtualOrInterfaceWithJValues<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, jvalue const*) 0x00000000efa88794
      art::JValue art::InvokeVirtualOrInterfaceWithJValues<_jmethodID*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, jvalue const*) 0x00000000efa888a2
      art::Thread::CreateCallback(void*) 0x00000000efacad22
      __pthread_start(void*) 0x00000000f324830c
      __start_thread 0x00000000f32008f0

      #2 Rendering Thread (QtThread)

      syscall 0x00000000f31faa1c __futex_wait_ex(void volatile*, bool, int, bool, timespec const*) 0x00000000f31ffc7e pthread_cond_wait 0x00000000f3247952 QWaitConditionPrivate::wait(QDeadlineTimer) qwaitcondition_unix.cpp:147 QWaitCondition::wait(QMutex*, QDeadlineTimer) qwaitcondition_unix.cpp:220 QAndroidPlatformOpenGLWindow::eglSurface(void*) qandroidplatformopenglwindow.cpp:135 QAndroidPlatformOpenGLContext::eglSurfaceForPlatformSurface(QPlatformSurface*) qandroidplatformopenglcontext.cpp:77 QEGLPlatformContext::makeCurrent(QPlatformSurface*) qeglplatformcontext.cpp:387 QAndroidPlatformOpenGLContext::makeCurrent(QPlatformSurface*) qandroidplatformopenglcontext.cpp:71 QOpenGLContext::makeCurrent(QSurface*) qopenglcontext.cpp:670 QRhiGles2::ensureContext(QSurface*) const qrhigles2.cpp:533 QRhiGles2::beginFrame(QRhiSwapChain*, QFlags<QRhi::BeginFrameFlag>) qrhigles2.cpp:1818 QRhi::beginFrame(QRhiSwapChain*, QFlags<QRhi::BeginFrameFlag>) qrhi.cpp:6764 QSGRenderThread::syncAndRender() qsgthreadedrenderloop.cpp:709 QSGRenderThread::run() qsgthreadedrenderloop.cpp:986 QThreadPrivate::start(void*)::$_0::operator()() const qthread_unix.cpp:356 void (anonymous namespace)::terminate_on_exception<QThreadPrivate::start(void*)::$_0>(QThreadPrivate::start(void*)::$_0&&) qthread_unix.cpp:292 QThreadPrivate::start(void*) qthread_unix.cpp:315 __pthread_start(void*) 0x00000000f324830c __start_thread 0x00000000f32008f0

      #3 Android Thread (kus.android)

      syscall 0x00000000f31faa1c
      QtLinuxFutex::_q_futex(int*, int, int, unsigned int, int*, int) qfutex_p.h:121
      void QtLinuxFutex::futexWait<QBasicAtomicInteger<unsigned int> >(QBasicAtomicInteger<unsigned int>&, QBasicAtomicInteger<unsigned int>::Type) qfutex_p.h:140
      bool futexSemaphoreTryAcquire_loop<false>(QBasicAtomicInteger<unsigned int>&, unsigned int, unsigned int, int) qsemaphore.cpp:206
      bool futexSemaphoreTryAcquire<false>(QBasicAtomicInteger<unsigned int>&, int, int) qsemaphore.cpp:262
      QSemaphore::acquire(int) qsemaphore.cpp:328
      QMetaObject::invokeMethodImpl(QObject*, QtPrivate::QSlotObjectBase*, Qt::ConnectionType, void*) qmetaobject.cpp:1546
      std::__ndk1::enable_if<((!(QtPrivate::FunctionPointer<QtAndroidAccessibility::descriptionForAccessibleObject(_JNIEnv*, _jobject*, int)::$_8>::IsPointerToMemberFunction)) && ((QtPrivate::FunctionPointer<QtAndroidAccessibility::descriptionForAccessibleObject(_JNIEnv*, _jobject*, int)::$_8>::ArgumentCount) == (-(1)))) && (!(std::is_convertible<QtAndroidAccessibility::descriptionForAccessibleObject(_JNIEnv*, _jobject*, int)::$_8, char const*>::value)), bool>::type QMetaObject::invokeMethod<QtAndroidAccessibility::descriptionForAccessibleObject(_JNIEnv*, _jobject*, int)::$_8>(QObject*, QtAndroidAccessibility::descriptionForAccessibleObject(_JNIEnv*, _jobject*, int)::$_8, Qt::ConnectionType, decltype(fp0())*) qobjectdefs.h:355
      void QtAndroidAccessibility::runInObjectContext<QtAndroidAccessibility::descriptionForAccessibleObject(_JNIEnv*, _jobject*, int)::$_8, QString>(QObject*, QtAndroidAccessibility::descriptionForAccessibleObject(_JNIEnv*, _jobject*, int)::$_8&&, QString*) androidjniaccessibility.cpp:103
      QtAndroidAccessibility::descriptionForAccessibleObject(_JNIEnv*, _jobject*, int) androidjniaccessibility.cpp:584
      art_quick_generic_jni_trampoline 0x00000000ef7620de
      art_quick_invoke_stub_internal 0x00000000ef75d5d6
      art_quick_invoke_static_stub 0x00000000efb7d610
      art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*) 0x00000000ef7b68fc
      art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*) 0x00000000ef8ced26
      bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x00000000ef8c7158
      void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*) 0x00000000ef76b0b0
      ExecuteSwitchImplAsm 0x00000000ef762c76
      art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.16561771350904891617) 0x00000000ef8c03c0
      art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*) 0x00000000ef8c697e
      bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x00000000ef8c713e
      void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*) 0x00000000ef76b0b0
      ExecuteSwitchImplAsm 0x00000000ef762c76
      art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.16561771350904891617) 0x00000000ef8c03c0
      art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*) 0x00000000ef8c697e
      bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x00000000ef8c713e
      void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*) 0x00000000ef769d38
      ExecuteSwitchImplAsm 0x00000000ef762c76
      art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.16561771350904891617) 0x00000000ef8c03c0
      art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*) 0x00000000ef8c697e
      bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x00000000ef8c713e
      void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*) 0x00000000ef769d38
      ExecuteSwitchImplAsm 0x00000000ef762c76
      art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.16561771350904891617) 0x00000000ef8c03c0
      art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*) 0x00000000ef8c697e
      bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x00000000ef8c713e
      void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*) 0x00000000ef769d38
      ExecuteSwitchImplAsm 0x00000000ef762c76
      art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.16561771350904891617) 0x00000000ef8c03c0
      art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*) 0x00000000ef8c697e
      bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x00000000ef8c713e
      void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*) 0x00000000ef769732
      ExecuteSwitchImplAsm 0x00000000ef762c76
      art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.16561771350904891617) 0x00000000ef8c03c0
      art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*) 0x00000000ef8c697e
      bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x00000000ef8c713e
      void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*) 0x00000000ef76b0b0
      ExecuteSwitchImplAsm 0x00000000ef762c76
      art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.16561771350904891617) 0x00000000ef8c03c0
      art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*) 0x00000000ef8c697e
      bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x00000000ef8c713e
      void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*) 0x00000000ef769d38
      ExecuteSwitchImplAsm 0x00000000ef762c76
      art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.16561771350904891617) 0x00000000ef8c03c0
      art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*) 0x00000000ef8c697e
      bool art::interpreter::DoCall<false, true>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x00000000ef8c78d6
      void art::interpreter::ExecuteSwitchImplCpp<true, false>(art::interpreter::SwitchImplContext*) 0x00000000ef790a10
      ExecuteSwitchImplAsm 0x00000000ef762c76
      art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.16561771350904891617) 0x00000000ef8c0296
      art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*) 0x00000000ef8c68ba
      artQuickToInterpreterBridge 0x00000000efb6040a
      art_quick_to_interpreter_bridge 0x00000000ef762164
      <unknown> 0x00000000ef762260

      Attachments

        For Gerrit Dashboard: QTBUG-105958
        # Subject Branch Project Status CR V

        Activity