diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2022-04-01 14:27:52 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2022-04-01 16:56:58 +0200 |
commit | b3b18ed165b7bab80e15f130fe7826595460539c (patch) | |
tree | a4ea5baf8d15ea275c89df8c1c203646d0867f98 /pyuno | |
parent | 93c1241eec9f5df84a96c57f8050efd4851cb0df (diff) |
Don't make UNO calls from PyThreadAttached regions (i.e., with the GIL locked)
...which caused e.g. UITest_writer_tests3 to occasionally hang with the
python.bin process thread 1 at
> File "sw/qa/uitest/writer_tests3/insertPageFooter.py", line 30, in delete_footer
[...]
i.e.,
> #4 ___pthread_cond_wait at /usr/src/debug/glibc-2.35-4.fc36.x86_64/nptl/pthread_cond_wait.c:618
> #5 0x00007ff9d6ad9c43 in cppu_threadpool::JobQueue::enter(void const*, bool) at cppu/source/threadpool/jobqueue.cxx:72
> #6 0x00007ff9d6ae8e79 in cppu_threadpool::ThreadPool::enter(rtl::ByteSequence const&, void const*) at cppu/source/threadpool/threadpool.cxx:303
> #7 0x00007ff9d6ae9278 in uno_threadpool_enter(uno_ThreadPool, void**) at cppu/source/threadpool/threadpool.cxx:407
> #8 0x00007ff9c7d016eb in binaryurp::Bridge::makeCall(rtl::OUString const&, com::sun::star::uno::TypeDescription const&, bool, std::__debug::vector<binaryurp::BinaryAny, std::allocator<binaryurp::BinaryAny> >&&, binaryurp::BinaryAny*, std::__debug::vector<binaryurp::BinaryAny, std::allocator<binaryurp::BinaryAny> >*) at binaryurp/source/bridge.cxx:604
> #9 0x00007ff9c7d322fc in binaryurp::Proxy::do_dispatch_throw(_typelib_TypeDescription const*, void*, void**, _uno_Any**) const at binaryurp/source/proxy.cxx:168
> #10 0x00007ff9c7d338cb in binaryurp::Proxy::do_dispatch(_typelib_TypeDescription const*, void*, void**, _uno_Any**) const at binaryurp/source/proxy.cxx:101
> #11 0x00007ff9d63222e0 in cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy*, typelib_TypeDescription const*, typelib_TypeDescriptionReference*, sal_Int32, typelib_MethodParameter*, void**, void**, void**, sal_uInt64*) at bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx:191
> #12 0x00007ff9d6322b59 in cpp_vtable_call(sal_Int32, sal_Int32, void**, void**, void**, sal_uInt64*) at bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx:389
> #13 0x00007ff9d63336ca in privateSnippetExecutor at instdir/program/libgcc3_uno.so
> #14 0x00007ff9d6241f38 in (anonymous namespace)::ImplIntrospectionAccess::hasByName(rtl::OUString const&) at stoc/source/inspect/introspection.cxx:1114
> #15 0x00007ff9d6b856b2 in pyuno::PyUNO_getattr(PyObject*, char*) at pyuno/source/module/pyuno.cxx:1392
[...]
doing a remote call to soffice.bin with GIL locked, and thread 4 at
> #6 0x00007ff9e51efa28 in take_gil at workdir/UnpackedTarball/python3/Python/ceval_gil.h:207
> #7 0x00007ff9e51f00d3 in PyEval_AcquireThread at workdir/UnpackedTarball/python3/Python/ceval.c:316
> #8 0x00007ff9d6b9b1e8 in pyuno::Adapter::invoke(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&, com::sun::star::uno::Sequence<short>&, com::sun::star::uno::Sequence<com::sun::star::uno::Any>&) at pyuno/source/module/pyuno_adapter.cxx:181
> #9 0x00007ff9d632b3e4 in gcc3::callVirtualMethod(void*, unsigned int, void*, _typelib_TypeDescriptionReference*, bool, unsigned long*, unsigned int, unsigned long*, double*) at bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx:77
> #10 0x00007ff9d632a4f1 in cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy*, bridges::cpp_uno::shared::VtableSlot, typelib_TypeDescriptionReference*, sal_Int32, typelib_MethodParameter*, void*, void**, uno_Any**) at bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:233
> #11 0x00007ff9d632a9e6 in bridges::cpp_uno::shared::unoInterfaceProxyDispatch(uno_Interface*, typelib_TypeDescription const*, void*, void**, uno_Any**) at bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:413
> #12 0x00007ff9d621384a in stoc_invadp::(anonymous namespace)::AdapterImpl::invoke at stoc/source/invocation_adapterfactory/iafactory.cxx:457
> #13 stoc_invadp::adapter_dispatch(uno_Interface*, typelib_TypeDescription const*, void*, void**, uno_Any**) at stoc/source/invocation_adapterfactory/iafactory.cxx:605
> #14 0x00007ff9c7d1a7db in binaryurp::IncomingRequest::execute_throw(binaryurp::BinaryAny*, std::__debug::vector<binaryurp::BinaryAny, std::allocator<binaryurp::BinaryAny> >*) const at include/typelib/typedescription.hxx:155
> #15 0x00007ff9c7d1d65f in binaryurp::IncomingRequest::execute() const at binaryurp/source/incomingrequest.cxx:78
> #16 0x00007ff9c7d33ad3 in binaryurp::(anonymous namespace)::request(void*) at ~/gcc/trunk/inst/include/c++/12.0.1/bits/unique_ptr.h:172
> #17 0x00007ff9d6ad9e1b in cppu_threadpool::JobQueue::enter(void const*, bool) at cppu/source/threadpool/jobqueue.cxx:100
> #18 0x00007ff9d6adbb80 in cppu_threadpool::ORequestThread::run() at cppu/source/threadpool/thread.cxx:164
[...]
processing an unrelated incoming call from soffice.bin and blocked trying to
lock the GIL. (The reason that thread 1 doesn't make progress is that the
soffice.bin process is also blocking with thread 6 at
> #8 osl::Guard<comphelper::SolarMutex>::Guard(comphelper::SolarMutex&) at include/osl/mutex.hxx:142
> #9 SolarMutexGuard::SolarMutexGuard() at include/vcl/svapp.hxx:1368
> #10 sw::(anonymous namespace)::XStyleFamily::hasByName(rtl::OUString const&) at sw/source/core/unocore/unostyle.cxx:923
> #11 0x00007f089d3d53e4 in gcc3::callVirtualMethod(void*, unsigned int, void*, _typelib_TypeDescriptionReference*, bool, unsigned long*, unsigned int, unsigned long*, double*) at bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx:77
> #12 0x00007f089d3d44f1 in cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy*, bridges::cpp_uno::shared::VtableSlot, typelib_TypeDescriptionReference*, sal_Int32, typelib_MethodParameter*, void*, void**, uno_Any**) at bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:233
> #13 0x00007f089d3d49e6 in bridges::cpp_uno::shared::unoInterfaceProxyDispatch(uno_Interface*, typelib_TypeDescription const*, void*, void**, uno_Any**) at bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:413
> #14 0x00007f089c1be7db in binaryurp::IncomingRequest::execute_throw(binaryurp::BinaryAny*, std::__debug::vector<binaryurp::BinaryAny, std::allocator<binaryurp::BinaryAny> >*) const at include/typelib/typedescription.hxx:155
> #15 0x00007f089c1c165f in binaryurp::IncomingRequest::execute() const at binaryurp/source/incomingrequest.cxx:78
> #16 0x00007f089c1d7ad3 in binaryurp::(anonymous namespace)::request(void*) at ~/gcc/trunk/inst/include/c++/12.0.1/bits/unique_ptr.h:172
> #17 0x00007f08a18ade1b in cppu_threadpool::JobQueue::enter(void const*, bool) at cppu/source/threadpool/jobqueue.cxx:100
> #18 0x00007f08a18afb80 in cppu_threadpool::ORequestThread::run() at cppu/source/threadpool/thread.cxx:164
[...]
processing the incoming call from python.bin thread 1 and blocked trying to lock
the SolarMutex, while thread 1 at
> #4 ___pthread_cond_wait at /usr/src/debug/glibc-2.35-4.fc36.x86_64/nptl/pthread_cond_wait.c:618
> #5 0x00007f08a18adc43 in cppu_threadpool::JobQueue::enter(void const*, bool) at cppu/source/threadpool/jobqueue.cxx:72
> #6 0x00007f08a18bce79 in cppu_threadpool::ThreadPool::enter(rtl::ByteSequence const&, void const*) at cppu/source/threadpool/threadpool.cxx:303
> #7 0x00007f08a18bd278 in uno_threadpool_enter(uno_ThreadPool, void**) at cppu/source/threadpool/threadpool.cxx:407
> #8 0x00007f089c1a56eb in binaryurp::Bridge::makeCall(rtl::OUString const&, com::sun::star::uno::TypeDescription const&, bool, std::__debug::vector<binaryurp::BinaryAny, std::allocator<binaryurp::BinaryAny> >&&, binaryurp::BinaryAny*, std::__debug::vector<binaryurp::BinaryAny, std::allocator<binaryurp::BinaryAny> >*) at binaryurp/source/bridge.cxx:604
> #9 0x00007f089c1d62fc in binaryurp::Proxy::do_dispatch_throw(_typelib_TypeDescription const*, void*, void**, _uno_Any**) const at binaryurp/source/proxy.cxx:168
> #10 0x00007f089c1d78cb in binaryurp::Proxy::do_dispatch(_typelib_TypeDescription const*, void*, void**, _uno_Any**) const at binaryurp/source/proxy.cxx:101
> #11 0x00007f089d3cc2e0 in cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy*, typelib_TypeDescription const*, typelib_TypeDescriptionReference*, sal_Int32, typelib_MethodParameter*, void**, void**, void**, sal_uInt64*) at bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx:191
> #12 0x00007f089d3ccb59 in cpp_vtable_call(sal_Int32, sal_Int32, void**, void**, void**, sal_uInt64*) at bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx:389
> #13 0x00007f089d3dd6ca in privateSnippetExecutor at instdir/program/libgcc3_uno.so
> #14 0x00007f08a6b5d170 in operator() at sfx2/source/notify/globalevents.cxx:491
> #15 comphelper::OInterfaceContainerHelper4<com::sun::star::document::XDocumentEventListener>::forEach<(anonymous namespace)::SfxGlobalEvents_Impl::implts_notifyListener(const com::sun::star::document::DocumentEvent&)::<lambda(const com::sun::star::uno::Reference<com::sun::star::document::XDocumentEventListener>&)> > at include/comphelper/interfacecontainer4.hxx:285
> #16 at sfx2/source/notify/globalevents.cxx:488
> #17 0x00007f08a6b04c8b in (anonymous namespace)::NotifySingleListenerIgnoreRE<com::sun::star::document::XDocumentEventListener, com::sun::star::document::DocumentEvent>::operator() (listener=Python Exception <class 'gdb.error'>: Dwarf Error: Cannot find DIE at 0x0 referenced in module instdir/program/libmergedlo.so
> #18 comphelper::OInterfaceContainerHelper2::forEach<com::sun::star::document::XDocumentEventListener, at include/comphelper/interfacecontainer2.hxx:271
> #19 SfxBaseModel::postEvent_Impl(rtl::OUString const&, com::sun::star::uno::Reference<com::sun::star::frame::XController2> const&, com::sun::star::uno::Any const&) at sfx2/source/doc/sfxbasemodel.cxx:3253
> #20 0x00007f08a6b066fe in SfxBaseModel::Notify(SfxBroadcaster&, SfxHint const&) at sfx2/source/doc/sfxbasemodel.cxx:2902
> #21 0x00007f08a6f15def in SfxBroadcaster::Broadcast(SfxHint const&) at svl/source/notify/SfxBroadcaster.cxx:39
> #22 0x00007f087d640650 in SwLayIdle::SwLayIdle(SwRootFrame*, SwViewShellImp*) at sw/source/core/layout/layact.cxx:2389
> #23 0x00007f087dc0832b in SwViewShell::LayoutIdle() at sw/source/core/view/viewsh.cxx:821
> #24 0x00007f087d2ba194 in sw::DocumentTimerManager::DoIdleJobs(Timer*) at sw/source/core/inc/rootfrm.hxx:206
> #25 0x00007f08a89fbd26 in Scheduler::CallbackTaskScheduling() at vcl/source/app/scheduler.cxx:472
> #26 0x00007f08a8ca8780 in SalTimer::CallCallback() at vcl/inc/saltimer.hxx:54
> #27 SvpSalInstance::CheckTimeout(bool) at vcl/headless/svpinst.cxx:212
> #28 0x00007f08a8ca99bd in SvpSalInstance::ImplYield(bool, bool) at vcl/headless/svpinst.cxx:452
> #29 0x00007f08a8ca9db1 in SvpSalInstance::DoYield(bool, bool) at vcl/headless/svpinst.cxx:524
> #30 0x00007f08a8a27d4c in ImplYield(bool, bool) at vcl/source/app/svapp.cxx:474
> #31 0x00007f08a8a28445 in Application::Execute() at vcl/source/app/svapp.cxx:452
[...]
is doing the remote call to python.bin thread 4 with the SolarMutex erroneously
locked. But lets concentrate on just fixing the python.bin deadlock in this
commit.)
The PyThreadDetach antiguard just covering the xInvocation->getValue call in the
"or a property" case had been added with
e0a1cd4dc7202795e4a60c73ea1608d86984add7 "fixed a deadlock", presumably without
taking into account that the xInvocation->hasMethod/hasProperty calls are
equally problematic.
Change-Id: I2483949df8213c3397a674be190224ee58c95c02
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132428
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'pyuno')
-rw-r--r-- | pyuno/source/module/pyuno.cxx | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/pyuno/source/module/pyuno.cxx b/pyuno/source/module/pyuno.cxx index c3de37b82a88..0db385793d86 100644 --- a/pyuno/source/module/pyuno.cxx +++ b/pyuno/source/module/pyuno.cxx @@ -1377,7 +1377,12 @@ static PyObject* PyUNO_getattr (PyObject* self, char* name) OUString attrName( OUString::createFromAscii( name ) ); //We need to find out if it's a method... - if (me->members->xInvocation->hasMethod (attrName)) + bool isMethod; + { + PyThreadDetach antiguard; + isMethod = me->members->xInvocation->hasMethod (attrName); + } + if (isMethod) { //Create a callable object to invoke this... PyRef ret = PyUNO_callable_new ( @@ -1389,14 +1394,19 @@ static PyObject* PyUNO_getattr (PyObject* self, char* name) } //or a property - if (me->members->xInvocation->hasProperty ( attrName)) + bool isProperty; + Any anyRet; { - //Return the value of the property - Any anyRet; + PyThreadDetach antiguard; + isProperty = me->members->xInvocation->hasProperty ( attrName); + if (isProperty) { - PyThreadDetach antiguard; + //Return the value of the property anyRet = me->members->xInvocation->getValue (attrName); } + } + if (isProperty) + { PyRef ret = runtime.any2PyObject(anyRet); Py_XINCREF( ret.get() ); return ret.get(); |