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>