sd/source/ui/framework/tools/FrameworkHelper.cxx | 27 ++++++++++++++++------- sd/source/ui/inc/framework/FrameworkHelper.hxx | 3 +- 2 files changed, 21 insertions(+), 9 deletions(-)
New commits: commit 6b4166d4b58e3b752647b52b5044a2577b1382da Author: Stephan Bergmann <stephan.bergm...@collabora.com> AuthorDate: Thu Aug 14 14:15:08 2025 +0200 Commit: Stephan Bergmann <stephan.bergm...@collabora.com> CommitDate: Thu Aug 14 23:03:12 2025 +0200 FrameworkHelper::WaitForEvent needs to stop listening when it gives up ...to avoid > warn:legacy.osl:1217871:1217871:sd/source/ui/framework/tools/FrameworkHelper.cxx:656: FrameworkHelper::WaitForEvent(), no event for a minute? giving up! > warn:legacy.osl:1217871:1217871:canvas/source/cairo/cairo_spritecanvas.cxx:82: CairoSpriteCanvas::SpriteCanvas: No Cairo capability > ================================================================= > ==1217871==ERROR: AddressSanitizer: stack-use-after-return on address 0x7fa9e7be2720 at pc 0x7fa98f2d3422 bp 0x7ffea89263e0 sp 0x7ffea89263d8 > WRITE of size 1 at 0x7fa9e7be2720 thread T0 > #0 0x7fa98f2d3421 in sd::framework::(anonymous namespace)::FlagUpdater::operator()(bool) const /sd/source/ui/framework/tools/FrameworkHelper.cxx:627:42 > #1 0x7fa98f2d330e in void std::__invoke_impl<void, sd::framework::(anonymous namespace)::FlagUpdater&, bool>(std::__invoke_other, sd::framework::(anonymous namespace)::FlagUpdater&, bool&&) /opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/invoke.h:61:14 > #2 0x7fa98f2d30ed in std::enable_if<is_invocable_r_v<void, sd::framework::(anonymous namespace)::FlagUpdater&, bool>, void>::type std::__invoke_r<void, sd::framework::(anonymous namespace)::FlagUpdater&, bool>(sd::framework::(anonymous namespace)::FlagUpdater&, bool&&) /opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/invoke.h:111:2 > #3 0x7fa98f2d2cad in std::_Function_handler<void (bool), sd::framework::(anonymous namespace)::FlagUpdater>::_M_invoke(std::_Any_data const&, bool&&) /opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/std_function.h:290:9 > #4 0x7fa98f2dc5eb in std::function<void (bool)>::operator()(bool) const /opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/std_function.h:591:9 > #5 0x7fa98f2ce73f in (anonymous namespace)::CallbackCaller::notifyConfigurationChange(sd::framework::ConfigurationChangeEvent const&) /sd/source/ui/framework/tools/FrameworkHelper.cxx:827:5 > #6 0x7fa98f0cb3be in sd::framework::ConfigurationControllerBroadcaster::NotifyListeners(std::__debug::vector<rtl::Reference<sd::framework::ConfigurationChangeListener>, std::allocator<rtl::Reference<sd::framework::ConfigurationChangeListener> > > const&, sd::framework::ConfigurationChangeEvent const&) /sd/source/ui/framework/configuration/ConfigurationControllerBroadcaster.cxx:84:24 > #7 0x7fa98f0cbe73 in sd::framework::ConfigurationControllerBroadcaster::NotifyListeners(sd::framework::ConfigurationChangeEvent const&) /sd/source/ui/framework/configuration/ConfigurationControllerBroadcaster.cxx:109:9 > #8 0x7fa98f12ee24 in sd::framework::ConfigurationUpdater::UpdateConfiguration() /sd/source/ui/framework/configuration/ConfigurationUpdater.cxx:169:28 > #9 0x7fa98f12d569 in sd::framework::ConfigurationUpdater::RequestUpdate(rtl::Reference<sd::framework::Configuration> const&) /sd/source/ui/framework/configuration/ConfigurationUpdater.cxx:108:13 > #10 0x7fa98f0536dc in sd::framework::ChangeRequestQueueProcessor::ProcessOneEvent() /sd/source/ui/framework/configuration/ChangeRequestQueueProcessor.cxx:158:33 > #11 0x7fa98f0521a9 in sd::framework::ChangeRequestQueueProcessor::ProcessEvent(void*) /sd/source/ui/framework/configuration/ChangeRequestQueueProcessor.cxx:115:5 > #12 0x7fa98f052018 in sd::framework::ChangeRequestQueueProcessor::LinkStubProcessEvent(void*, void*) /sd/source/ui/framework/configuration/ChangeRequestQueueProcessor.cxx:109:1 > #13 0x7fa9caadaf2d in Link<void*, void>::Call(void*) const /include/tools/link.hxx:105:45 > #14 0x7fa9caac0560 in ImplHandleUserEvent(ImplSVEvent*) /vcl/source/window/winproc.cxx:2312:30 > #15 0x7fa9caaab2aa in ImplWindowFrameProc(vcl::Window*, SalEvent, void const*) /vcl/source/window/winproc.cxx:2876:13 > #16 0x7fa9ce83a5f2 in SalFrame::CallCallback(SalEvent, void const*) const /vcl/inc/salframe.hxx:310:29 > #17 0x7fa9ce8e7311 in SvpSalInstance::ProcessEvent(SalUserEventList::SalUserEvent) /vcl/headless/svpinst.cxx:284:22 > #18 0x7fa9ce8e7aa2 in non-virtual thunk to SvpSalInstance::ProcessEvent(SalUserEventList::SalUserEvent) /vcl/headless/svpinst.cxx > #19 0x7fa9cd06f7a3 in SalUserEventList::DispatchUserEvents(bool)::$_0::operator()() const /vcl/source/app/salusereventlist.cxx:119:58 > #20 0x7fa9cd06ef3a in SalUserEventList::DispatchUserEvents(bool) /vcl/source/app/salusereventlist.cxx:120:13 > #21 0x7fa9ce8eb7ba in SvpSalInstance::ImplYield(bool, bool) /vcl/headless/svpinst.cxx:437:22 > #22 0x7fa9ce8edfd3 in SvpSalInstance::DoYield(bool, bool) /vcl/headless/svpinst.cxx:516:21 > #23 0x7fa9cd4d1a1a in ImplYield(bool, bool) /vcl/source/app/svapp.cxx:385:48 > #24 0x7fa9cd4d28cf in Scheduler::ProcessEventsToIdle() /vcl/source/app/svapp.cxx:435:12 > #25 0x7fa9a610ec3c in SdUiImpressTest::typeKey(SdXImpressDocument*, unsigned short) /sd/qa/unit/uiimpress.cxx:103:5 > #26 0x7fa9a619cf17 in testTdf166647_userpaint::TestBody() /sd/qa/unit/uiimpress.cxx:2012:5 > #27 0x7fa9a6327587 in void std::__invoke_impl<void, void (testTdf166647_userpaint::*&)(), testTdf166647_userpaint*&>(std::__invoke_memfun_deref, void (testTdf166647_userpaint::*&)(), testTdf166647_userpaint*&) /opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/invoke.h:74:14 > #28 0x7fa9a63271f4 in std::__invoke_result<void (testTdf166647_userpaint::*&)(), testTdf166647_userpaint*&>::type std::__invoke<void (testTdf166647_userpaint::*&)(), testTdf166647_userpaint*&>(void (testTdf166647_userpaint::*&)(), testTdf166647_userpaint*&) /opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/invoke.h:96:14 > #29 0x7fa9a6327070 in void std::_Bind<void (testTdf166647_userpaint::* (testTdf166647_userpaint*))()>::__call<void, 0ul>(std::tuple<>&&, std::_Index_tuple<0ul>) /opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/functional:495:11 > #30 0x7fa9a6326dd4 in void std::_Bind<void (testTdf166647_userpaint::* (testTdf166647_userpaint*))()>::operator()<void>() /opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/functional:580:17 > #31 0x7fa9a6326c4c in void std::__invoke_impl<void, std::_Bind<void (testTdf166647_userpaint::* (testTdf166647_userpaint*))()>&>(std::__invoke_other, std::_Bind<void (testTdf166647_userpaint::* (testTdf166647_userpaint*))()>&) /opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/invoke.h:61:14 > #32 0x7fa9a6326afc in std::enable_if<is_invocable_r_v<void, std::_Bind<void (testTdf166647_userpaint::* (testTdf166647_userpaint*))()>&>, void>::type std::__invoke_r<void, std::_Bind<void (testTdf166647_userpaint::* (testTdf166647_userpaint*))()>&>(std::_Bind<void (testTdf166647_userpaint::* (testTdf166647_userpaint*))()>&) /opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/invoke.h:111:2 > #33 0x7fa9a632629c in std::_Function_handler<void (), std::_Bind<void (testTdf166647_userpaint::* (testTdf166647_userpaint*))()> >::_M_invoke(std::_Any_data const&) /opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/std_function.h:290:9 > #34 0x7fa9a6217041 in std::function<void ()>::operator()() const /opt/rh/gcc-toolset-12/root/usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/std_function.h:591:9 > #35 0x7fa9a6325668 in CppUnit::TestCaller<testTdf166647_userpaint>::runTest() /workdir/UnpackedTarball/cppunit/include/cppunit/TestCaller.h:175:7 > #36 0x7fa9ecf0988b in CppUnit::TestCaseMethodFunctor::operator()() const (/workdir/UnpackedTarball/cppunit/src/cppunit/.libs/libcppunit-1.15.so.1+0x31688b) > #37 0x7fa9ed3c86c0 in (anonymous namespace)::Protector::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) /test/source/vclbootstrapprotector.cxx:37:14 > #38 0x7fa9eced8ccc in CppUnit::ProtectorChain::ProtectFunctor::operator()() const (/workdir/UnpackedTarball/cppunit/src/cppunit/.libs/libcppunit-1.15.so.1+0x2e5ccc) > #39 0x7fa9e7651410 in (anonymous namespace)::Prot::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) /unotest/source/cpp/unobootstrapprotector/unobootstrapprotector.cxx:78:12 > #40 0x7fa9eced8ccc in CppUnit::ProtectorChain::ProtectFunctor::operator()() const (/workdir/UnpackedTarball/cppunit/src/cppunit/.libs/libcppunit-1.15.so.1+0x2e5ccc) > #41 0x7fa9ed2ff0ae in (anonymous namespace)::Prot::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) /unotest/source/cpp/unoexceptionprotector/unoexceptionprotector.cxx:181:16 > #42 0x7fa9eced8ccc in CppUnit::ProtectorChain::ProtectFunctor::operator()() const (/workdir/UnpackedTarball/cppunit/src/cppunit/.libs/libcppunit-1.15.so.1+0x2e5ccc) > #43 0x7fa9ece619df in CppUnit::DefaultProtector::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (/workdir/UnpackedTarball/cppunit/src/cppunit/.libs/libcppunit-1.15.so.1+0x26e9df) > #44 0x7fa9eced8ccc in CppUnit::ProtectorChain::ProtectFunctor::operator()() const (/workdir/UnpackedTarball/cppunit/src/cppunit/.libs/libcppunit-1.15.so.1+0x2e5ccc) > #45 0x7fa9eced2498 in CppUnit::ProtectorChain::protect(CppUnit::Functor const&, CppUnit::ProtectorContext const&) (/workdir/UnpackedTarball/cppunit/src/cppunit/.libs/libcppunit-1.15.so.1+0x2df498) > #46 0x7fa9ecf7a1e7 in CppUnit::TestResult::protect(CppUnit::Functor const&, CppUnit::Test*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (/workdir/UnpackedTarball/cppunit/src/cppunit/.libs/libcppunit-1.15.so.1+0x3871e7) > #47 0x7fa9ecf080eb in CppUnit::TestCase::run(CppUnit::TestResult*) (/workdir/UnpackedTarball/cppunit/src/cppunit/.libs/libcppunit-1.15.so.1+0x3150eb) > #48 0x7fa9ecf0bbc1 in CppUnit::TestComposite::doRunChildTests(CppUnit::TestResult*) (/workdir/UnpackedTarball/cppunit/src/cppunit/.libs/libcppunit-1.15.so.1+0x318bc1) > #49 0x7fa9ecf0ae18 in CppUnit::TestComposite::run(CppUnit::TestResult*) (/workdir/UnpackedTarball/cppunit/src/cppunit/.libs/libcppunit-1.15.so.1+0x317e18) > #50 0x7fa9ecf0bbc1 in CppUnit::TestComposite::doRunChildTests(CppUnit::TestResult*) (/workdir/UnpackedTarball/cppunit/src/cppunit/.libs/libcppunit-1.15.so.1+0x318bc1) > #51 0x7fa9ecf0ae18 in CppUnit::TestComposite::run(CppUnit::TestResult*) (/workdir/UnpackedTarball/cppunit/src/cppunit/.libs/libcppunit-1.15.so.1+0x317e18) > #52 0x7fa9ecfaf846 in CppUnit::TestRunner::WrappingSuite::run(CppUnit::TestResult*) (/workdir/UnpackedTarball/cppunit/src/cppunit/.libs/libcppunit-1.15.so.1+0x3bc846) > #53 0x7fa9ecf78c9e in CppUnit::TestResult::runTest(CppUnit::Test*) (/workdir/UnpackedTarball/cppunit/src/cppunit/.libs/libcppunit-1.15.so.1+0x385c9e) > #54 0x7fa9ecfb0712 in CppUnit::TestRunner::run(CppUnit::TestResult&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (/workdir/UnpackedTarball/cppunit/src/cppunit/.libs/libcppunit-1.15.so.1+0x3bd712) > #55 0x50a2bb in (anonymous namespace)::ProtectedFixtureFunctor::run() const /sal/cppunittester/cppunittester.cxx:328:20 > #56 0x506d13 in main2() /sal/cppunittester/cppunittester.cxx:482:16 > #57 0x50512f in sal_main() /sal/cppunittester/cppunittester.cxx:627:14 > #58 0x504f6e in main /sal/cppunittester/cppunittester.cxx:622:1 (<https://ci.libreoffice.org/job/lo_ubsan/3648/>) as seen during (recently introduced) CppunitTest_sd_uiimpress testTdf166647_userpaint::TestBody. (I assume that there is a pre-existing race accessing CallbackCaller::mxConfigurationController, and that an additional CallbackCaller::stop accessing it doesn't make things worse, so left that point alone for now.) Change-Id: I069b2935b5ca6430710d401b4cae32e4b9c8b7f1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189598 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <stephan.bergm...@collabora.com> diff --git a/sd/source/ui/framework/tools/FrameworkHelper.cxx b/sd/source/ui/framework/tools/FrameworkHelper.cxx index af5392dfb9a7..e7a914c72c1c 100644 --- a/sd/source/ui/framework/tools/FrameworkHelper.cxx +++ b/sd/source/ui/framework/tools/FrameworkHelper.cxx @@ -48,7 +48,7 @@ using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::drawing::framework; -namespace { +namespace sd::framework { //----- CallbackCaller -------------------------------------------------------- @@ -91,6 +91,8 @@ public: // ConfigurationChangeListener virtual void notifyConfigurationChange (const sd::framework::ConfigurationChangeEvent& rEvent) override; + void stop(); + private: sd::framework::ConfigurationChangeEventType mnEventType; rtl::Reference<::sd::framework::ConfigurationController> mxConfigurationController; @@ -98,6 +100,10 @@ private: ::sd::framework::FrameworkHelper::Callback maCallback; }; +} + +namespace { + //----- LifetimeController ---------------------------------------------------- typedef comphelper::WeakComponentImplHelper < @@ -641,7 +647,7 @@ void FrameworkHelper::WaitForEvent (ConfigurationChangeEventType rsEventType) co { bool bConfigurationUpdateSeen (false); - RunOnEvent( + auto const caller = RunOnEvent( rsEventType, FrameworkHelperAllPassFilter(), FlagUpdater(bConfigurationUpdateSeen)); @@ -654,6 +660,7 @@ void FrameworkHelper::WaitForEvent (ConfigurationChangeEventType rsEventType) co if( (osl_getGlobalTimer() - nStartTime) > 60000 ) { OSL_FAIL("FrameworkHelper::WaitForEvent(), no event for a minute? giving up!"); + caller->stop(); break; } } @@ -664,12 +671,12 @@ void FrameworkHelper::WaitForUpdate() const WaitForEvent(ConfigurationChangeEventType::ConfigurationUpdateEnd); } -void FrameworkHelper::RunOnEvent( +rtl::Reference<CallbackCaller> FrameworkHelper::RunOnEvent( ConfigurationChangeEventType rsEventType, const ConfigurationChangeEventFilter& rFilter, const Callback& rCallback) const { - new CallbackCaller(mrBase,rsEventType,rFilter,rCallback); + return new CallbackCaller(mrBase,rsEventType,rFilter,rCallback); } void FrameworkHelper::disposing (const lang::EventObject& rEventObject) @@ -748,10 +755,6 @@ FrameworkHelperResourceIdFilter::FrameworkHelperResourceIdFilter ( { } -} // end of namespace sd::framework - -namespace { - //===== CallbackCaller ======================================================== CallbackCaller::CallbackCaller ( @@ -825,6 +828,10 @@ void CallbackCaller::notifyConfigurationChange ( return; maCallback(true); + stop(); +} + +void CallbackCaller::stop() { if (mxConfigurationController.is()) { // Reset the reference to the configuration controller so that @@ -838,6 +845,10 @@ void CallbackCaller::notifyConfigurationChange ( } } +} // end of namespace sd::framework + +namespace { + //----- LifetimeController ------------------------------------------------- LifetimeController::LifetimeController (::sd::ViewShellBase& rBase) diff --git a/sd/source/ui/inc/framework/FrameworkHelper.hxx b/sd/source/ui/inc/framework/FrameworkHelper.hxx index c459ef00b881..c39ee69d12b4 100644 --- a/sd/source/ui/inc/framework/FrameworkHelper.hxx +++ b/sd/source/ui/inc/framework/FrameworkHelper.hxx @@ -34,6 +34,7 @@ class ViewShellBase; namespace sd::framework { +class CallbackCaller; struct ConfigurationChangeEvent; class ConfigurationController; class AbstractView; @@ -288,7 +289,7 @@ private: @param rCallback The callback functor to be called. */ - void RunOnEvent( + rtl::Reference<CallbackCaller> RunOnEvent( ConfigurationChangeEventType rsEventType, const ConfigurationChangeEventFilter& rFilter, const Callback& rCallback) const;