Files
odfstudio/include
Caolán McNamara f2e8dc899d prevent BufferedDecomposition[Group]Primitive2D from being resurrected
The BufferedDecompositionFlusher thread is waiting for the SolarMutex
and has accumulated a bunch of rtl::References to Primitive2Ds in
aRemoved[1|2] created from direct pointers to Primitive2Ds during the
earlier phase.

Thread 6 (Thread 0x7fd2e27fe6c0 (LWP 3729389)):
 #0  0x00007fd313d3012b in  () at /lib/x86_64-linux-gnu/libc.so.6
 #1  0x00007fd313d364da in pthread_mutex_lock () at /lib/x86_64-linux-gnu/libc.so.6
 #2  0x00007fd3140a75f1 in osl_acquireMutex(oslMutex) (pMutex=0x556f87223470) at sal/osl/unx/mutex.cxx:93
         nRet = 32723
 #3  0x00007fd30e02be53 in osl::Mutex::acquire() (this=0x556f87223968) at include/osl/mutex.hxx:63
         pInst = 0x556f87223830
         __PRETTY_FUNCTION__ = "virtual void SvpSalYieldMutex::doAcquire(sal_uInt32)"
 #4  SvpSalYieldMutex::doAcquire(unsigned int) (this=0x556f87223960, nLockCount=1) at vcl/headless/svpinst.cxx:376
         pInst = 0x556f87223830
         __PRETTY_FUNCTION__ = "virtual void SvpSalYieldMutex::doAcquire(sal_uInt32)"
 #5  0x00007fd312bcd4fc in comphelper::SolarMutex::acquire(unsigned int) (this=<optimized out>, nLockCount=nLockCount@entry=1) at include/comphelper/solarmutex.hxx:86
         __PRETTY_FUNCTION__ = "void comphelper::SolarMutex::acquire(sal_uInt32)"
 #6  0x00007fd312bcd6bd in osl::Guard<comphelper::SolarMutex>::Guard(comphelper::SolarMutex*) (this=<optimized out>, pT_=<optimized out>) at include/osl/mutex.hxx:137
 #7  0x00007fd312bccd53 in drawinglayer::primitive2d::BufferedDecompositionFlusher::run() (this=0x7fd2d4159230) at drawinglayer/source/primitive2d/BufferedDecompositionFlusher.cxx:154
         aGuard = {pT = 0x556f87223960}
         aNow = {__d = {__r = 64556205175663173}}
         aRemoved1 = std::__debug::vector of length 1155, capacity 2048 =

The active thread 1 asserts that the reference count of a
SimpleReferenceObject isn't zero during dtor.

Thread 1 (Thread 0x7fd2e2fff6c0 (LWP 3726667)):
 #21 0x00007fd313c2760a in salhelper::SimpleReferenceObject::~SimpleReferenceObject() (this=this@entry=0x7fd2d62f51f0, __in_chrg=<optimized out>) at salhelper/source/simplereferenceobject.cxx:29
 #22 0x00007fd312bcbc57 in drawinglayer::primitive2d::BasePrimitive2D::~BasePrimitive2D() (this=this@entry=0x7fd2d62f51f0, __in_chrg=<optimized out>) at drawinglayer/source/primitive2d/baseprimitive2d.cxx:34
 #23 0x00007fd312bcc368 in drawinglayer::primitive2d::BufferedDecompositionPrimitive2D::~BufferedDecompositionPrimitive2D() (this=this@entry=0x7fd2d62f51f0, __in_chrg=<optimized out>) at drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx:69
 #24 0x00007fd310300136 in drawinglayer::primitive2d::SdrGrafPrimitive2D::~SdrGrafPrimitive2D() (this=0x7fd2d62f51f0, __in_chrg=<optimized out>) at svx/inc/sdr/primitive2d/sdrgrafprimitive2d.hxx:29
 #25 0x00007fd310300141 in drawinglayer::primitive2d::SdrGrafPrimitive2D::~SdrGrafPrimitive2D() (this=0x7fd2d62f51f0, __in_chrg=<optimized out>) at svx/inc/sdr/primitive2d/sdrgrafprimitive2d.hxx:29
 #26 0x00007fd312bcc5d3 in salhelper::SimpleReferenceObject::release() (this=<optimized out>) at include/salhelper/simplereferenceobject.hxx:83
 #27 0x00007fd312bd1e63 in rtl::Reference<drawinglayer::primitive2d::BasePrimitive2D>::~Reference() (this=0x7fd2d62f4b10, __in_chrg=<optimized out>) at include/rtl/ref.hxx:126
 #28 std::destroy_at<rtl::Reference<drawinglayer::primitive2d::BasePrimitive2D> >(rtl::Reference<drawinglayer::primitive2d::BasePrimitive2D>*) (__location=0x7fd2d62f4b10) at /usr/include/c++/12/bits/stl_construct.h:88
 #29 std::_Destroy<rtl::Reference<drawinglayer::primitive2d::BasePrimitive2D> >(rtl::Reference<drawinglayer::primitive2d::BasePrimitive2D>*) (__pointer=0x7fd2d62f4b10) at /usr/include/c++/12/bits/stl_construct.h:149

So, what if a BufferedDecompositionPrimitive2D was registered with
BufferedDecompositionFlusher, so a direct pointer to it exists.

On Thread 0 the BufferedDecompositionPrimitive2D ref count hits 0,
dtoring starts.

Meanwhile Thread 6 merrily spins its loop, creates a rtl::Reference from
the BufferedDecompositionPrimitive2D, ref count goes back up to 1.

BufferedDecompositionPrimitive2D::dtor gets around to unregistering
itself from BufferedDecompositionFlusher, but that doesn't matter
because the rtl::Reference to the primitive already exists in aRemoved,
dtor hits assert that refcount isn't 0

Change-Id: Iac0a03bb7cbadf949ba1ac00d69cf15cc2505e18
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192674
Tested-by: Jenkins
Tested-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
2025-10-23 15:46:19 +02:00
..
2025-10-21 17:48:22 +02:00
…
2025-10-10 06:28:57 +02:00
…
2025-10-11 20:28:09 +02:00
…
2025-10-14 20:24:09 +02:00
2025-10-19 10:43:41 +02:00
2025-10-15 10:22:38 +02:00
2025-09-05 19:45:45 +02:00
2025-09-11 18:14:53 +02:00
…
…
…
…
…