diff options
author | Caolán McNamara <caolanm@redhat.com> | 2013-04-18 13:13:43 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2013-04-18 13:25:16 +0100 |
commit | 3d6424a752902bba513102834966868f609d91e6 (patch) | |
tree | e0abb28a1d00947b97441e34333ddebf6e2271ae | |
parent | fe6c9239d787a5d6057addbd38c5bb42760bbceb (diff) |
Related: rhbz#761009 lp#766153 lp#892904 HandleFontOptions crash
The mpServerFont member of a ImplServerFontEntry must not be deleted while the
ImplServerFontEntry still exists
see also 39cbce553da1834f78b77f48b2f1be9578d6cc05 for another reason a crash in
the same place can happen. Its impossible from traces in crashes before
39cbce553da1834f78b77f48b2f1be9578d6cc05 was fixed to distinguish those crashes
from this crash.
This crash is a regression due to 7a416820ab5e03f8b988656e0f6a592cb1e81d07
where we went from modifying pServerFont in X11SalGraphics::setFont directly to
modifying it/a-different-one indirectly via ImplServerFontEntry
The various font caches and font thing lifecycles of LibreOffice are somewhat
confusing.
This crash had eluded me for years, to reproduce:
insert->special chars->select a font with loads of glyphs, i.e. "AR PL UKai CN"
click on the first row of glyphs and hold down page-down until you hit the
bottom, then page-up until you hit the top. Pre patch it won't survive the
whole down+up (and valgrind will moan quite a bit)
Change-Id: Ifde0cb375f487c556b04a640d77765a7dc2f0913
-rw-r--r-- | vcl/generic/glyphs/glyphcache.cxx | 13 | ||||
-rw-r--r-- | vcl/inc/generic/glyphcache.hxx | 3 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/salgdi3.cxx | 8 |
3 files changed, 19 insertions, 5 deletions
diff --git a/vcl/generic/glyphs/glyphcache.cxx b/vcl/generic/glyphs/glyphcache.cxx index fa3659a3990f..a6849ececd8b 100644 --- a/vcl/generic/glyphs/glyphcache.cxx +++ b/vcl/generic/glyphs/glyphcache.cxx @@ -411,9 +411,22 @@ ImplServerFontEntry::ImplServerFontEntry( FontSelectPattern& rFSD ) // ----------------------------------------------------------------------- +void ImplServerFontEntry::SetServerFont(ServerFont* p) +{ + if (p == mpServerFont) + return; + if (mpServerFont) + mpServerFont->Release(); + mpServerFont = p; + if (mpServerFont) + mpServerFont->AddRef(); +} + ImplServerFontEntry::~ImplServerFontEntry() { // TODO: remove the ServerFont here instead of in the GlyphCache + if (mpServerFont) + mpServerFont->Release(); } // ======================================================================= diff --git a/vcl/inc/generic/glyphcache.hxx b/vcl/inc/generic/glyphcache.hxx index 24cda3c21040..d9f8378a28d9 100644 --- a/vcl/inc/generic/glyphcache.hxx +++ b/vcl/inc/generic/glyphcache.hxx @@ -225,6 +225,7 @@ public: private: friend class GlyphCache; friend class ServerFontLayout; + friend class ImplServerFontEntry; friend class X11SalGraphics; void AddRef() const { ++mnRefCount; } @@ -302,7 +303,7 @@ private: public: ImplServerFontEntry( FontSelectPattern& ); virtual ~ImplServerFontEntry(); - void SetServerFont( ServerFont* p) { mpServerFont = p; } + void SetServerFont(ServerFont* p); void HandleFontOptions(); }; diff --git a/vcl/unx/generic/gdi/salgdi3.cxx b/vcl/unx/generic/gdi/salgdi3.cxx index 30a1e3b1e6e0..ba6628a8ab71 100644 --- a/vcl/unx/generic/gdi/salgdi3.cxx +++ b/vcl/unx/generic/gdi/salgdi3.cxx @@ -194,10 +194,10 @@ bool X11SalGraphics::setFont( const FontSelectPattern *pEntry, int nFallbackLeve // apply font specific-hint settings if needed // TODO: also disable it for reference devices - if( !bPrinter_ ) - { - ImplServerFontEntry* pSFE = static_cast<ImplServerFontEntry*>( pEntry->mpFontEntry ); - pSFE->HandleFontOptions(); + if( !bPrinter_ ) + { + ImplServerFontEntry* pSFE = static_cast<ImplServerFontEntry*>( pEntry->mpFontEntry ); + pSFE->HandleFontOptions(); } return true; |