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;

Reply via email to