diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2023-12-18 17:21:15 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2023-12-18 18:13:54 +0100 |
commit | 164fb25f7b2db7d833d6d0f28e49c5cac68426b3 (patch) | |
tree | a9795cda73cdff8f10b01f38d2419fbe31aa83b2 /include/sfx2 | |
parent | d2c54902102ab9ee40cca16ae21f1bf3ad7c4066 (diff) |
tdf#158686 sw floattable: fix print preview crash
Regression from commit b8521d969ab5be4fc947e467d4afe969f9d3b563
(tdf#157263 sw floattable: prefer join over split after moving fwd,
2023-09-25), enabling Options -> Writer -> Formatting Aids -> Hidden
Characters, then opening the bugdoc, finally Toggle Print Preview on the
toolbar resulted in a crash.
We have a memory corruption here:
==11968==ERROR: AddressSanitizer: heap-use-after-free on address 0x60f0000734e0 at pc 0x7f473822d2ee bp 0x7fffdadd3660 sp 0x7fffdadd3658
READ of size 8 at 0x60f0000734e0 thread T0
#0 0x7f473822d2ed in rtl::Reference<FmXFormShell>::operator->() const /include/rtl/ref.hxx:216:9
#1 0x7f473821feeb in FmFormShell::IsActiveControl() const /svx/source/form/fmshell.cxx:1227:12
#2 0x7f46dad4d52a in SwView::SelectShell() /sw/source/uibase/uiview/view.cxx:296:40
#3 0x7f46dad496a6 in SwView::AttrChangedNotify(LinkParamNone*) /sw/source/uibase/uiview/view.cxx:572:13
...
#32 0x7f4748944cda in SfxViewFrame::SwitchToViewShell_Impl(unsigned short, bool) /sfx2/source/view/viewfrm.cxx:2552:32
#33 0x7f47488f4e3b in SfxViewFrame::ExecView_Impl(SfxRequest&) /sfx2/source/view/viewfrm.cxx:2637:29
freed by thread T0 here:
#0 0x5568ff2f9a7b in operator delete(void*, unsigned long) /home/abuild/rpmbuild/BUILD/llvm-15.0.7.src/build/../projects/compiler-rt/lib/asan/asan_new_delete.cpp:164:3
#1 0x7f4738214346 in FmFormShell::~FmFormShell() /svx/source/form/fmshell.cxx:181:1
#2 0x7f4746b04b9d in SfxDispatcher::FlushImpl() /sfx2/source/control/dispatch.cxx:1412:13
#3 0x7f4746aff767 in SfxDispatcher::Flush() /sfx2/source/control/dispatch.cxx:157:26
#4 0x7f47489100dc in SfxViewFrame::PopShellAndSubShells_Impl(SfxViewShell&) /sfx2/source/view/viewfrm.cxx:1100:24
#5 0x7f47489441a3 in SfxViewFrame::SwitchToViewShell_Impl(unsigned short, bool) /sfx2/source/view/viewfrm.cxx:2538:13
#6 0x7f47488f4e3b in SfxViewFrame::ExecView_Impl(SfxRequest&) /sfx2/source/view/viewfrm.cxx:2637:29
I.e. a new SwPagePreview replaces the old SwView, but the order is that
SfxViewFrame::SwitchToViewShell_Impl() starts with deleting the
SfxShells of the old SwView in PopShellAndSubShells_Impl(), then it
creates the new shell, finally deletes the old shell. Given that the new
shell hides hidden characters and the old shell did not, this triggers a
size notification for the half-deleted old shell and we crash.
Seeing that SwView::AttrChangedNotify() already had code to delay the
selection of an SfxShell in the old SwView, fix the problem by
introducing a new flag that allows not selecting an SfxShell at all if
the old view is known to be deleted in the near future anyway.
An alternative would be to make sure that all relevant pointers are
maintained using an SfxBroadcaster / SfxListener protocol, but after
fixing some 4 of them and that's still not enough, probably it's better
to handle this at a higher level. It's also a bit unclear how this
"worked" in the past; looks like the old view didn't get the size change
notification by accident.
Change-Id: I423ff946f8235848cc3a870bc52fcf88a721fd2b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160925
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
Diffstat (limited to 'include/sfx2')
-rw-r--r-- | include/sfx2/viewsh.hxx | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx index fff558ba28a4..0cbadc5072dc 100644 --- a/include/sfx2/viewsh.hxx +++ b/include/sfx2/viewsh.hxx @@ -227,6 +227,10 @@ public: SfxViewShell( SfxViewFrame& rFrame, SfxViewShellFlags nFlags ); virtual ~SfxViewShell() override; + /// Informs the view shell that it'll be deleted before the main loop processes the next user + /// input. + virtual void SetDying() {} + SfxInPlaceClient* GetIPClient() const; SfxInPlaceClient* GetUIActiveClient() const; SfxInPlaceClient* FindIPClient( const css::uno::Reference < css::embed::XEmbeddedObject >& xObj, vcl::Window *pObjParentWin ) const; |