The number one reason why "make check" fails for me is a SEGV in
soffice.bin during termination of JunitTest_sc_unoapi, namely at
#0 0x00007f4906ecc0d2 in ScGlobal::GetRscString (nIndex=71) at
sc/source/core/data/global.cxx:355
#1 0x00007f4906f5e968 in ScAutoFormat::ScAutoFormat (this=0x335c510, nLim=4,
nDel=4, bDup=0 '\000') at sc/source/core/tool/autoform.cxx:898
#2 0x00007f4906ecbe93 in ScGlobal::GetAutoFormat () at
sc/source/core/data/global.cxx:304
#3 0x00007f490749b799 in ScAutoFormatObj::~ScAutoFormatObj
(this=0x7f48fd089a10) at sc/source/ui/unoobj/afmtuno.cxx:441
#4 0x00007f490749b880 in ScAutoFormatObj::~ScAutoFormatObj
(this=0x7f48fd089a10) at sc/source/ui/unoobj/afmtuno.cxx:447
#5 0x00007f492e87acd1 in cppu::OWeakObject::release (this=0x7f48fd089a10) at
cppuhelper/source/weak.cxx:213
[...]
#40 0x00007f491736fdcc in binaryurp::Bridge::terminate (this=0x7f491538f1d0) at
binaryurp/source/bridge.cxx:271
[...]
#55 0x00007f492f7d2377 in desktop::Desktop::DeregisterServices
(this=0x7ffff56496c0) at desktop/source/app/appinit.cxx:378
#56 0x00007f492f7ba4ee in desktop::Desktop::doShutdown (this=0x7ffff56496c0) at
desktop/source/app/app.cxx:1875
#57 0x00007f492f7b9a9d in desktop::Desktop::Main (this=0x7ffff56496c0) at
desktop/source/app/app.cxx:1845
#58 0x00007f492af3c6de in ImplSVMain () at vcl/source/app/svmain.cxx:178
#59 0x00007f492af3c824 in SVMain () at vcl/source/app/svmain.cxx:215
#60 0x00007f492f7f438a in soffice_main () at
desktop/source/app/sofficemain.cxx:67
#61 0x0000000000400734 in sal_main () at desktop/source/app/main.c:34
#62 0x0000000000400719 in main (argc=9, argv=0x7ffff5649878) at
desktop/source/app/main.c:33
ScGlobal::ppRscString has apparently already been cleared at this point.
But looking deeper down the stack, there is no real reason to create a
fresh ScAutoFormat at all -- ~ScAutoFormatObj does
ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
if ( pFormats && pFormats->IsSaveLater() )
but the freshly created ScAutoFormat (from ScGlobal::GetAutoFormat) has
bSaveLater set to false, so the condition would correctly already
evaluate to false if ScGlobal::GetAutoFormat would return null here. It
is also curious that pFormats is checked for null here, even though
ScGlobal::GetAutoFormat never returns null.
With that insight, I inspected all the other calls to
ScGlobal::GetAutoFormat, and many (but not all) of them too would only
dereference the returned ScAutoFormat pointer after checking it for
non-nullness. So I came up with the attached patch, introducing
ScGlobal::GetOrCreateAutoFormat for the few cases that apparently
require a non-null ScAutoFormat, and letting ScGlobal::GetAutoFormat
return null in case ScGlobal::pAutoFormat is null.
However, I had to fix one of the non-null--checking cases to use
GetOrCreateAutoFormat, as otherwise
sc/CppunitTest_sc_tableautoformatfield would fail with unexpected
IndexOutOfBoundsExceptions.
So, I would appreciate it if some Calc aficionado could look at the
patch, whether it actually makes any sense. It would be crucial to look
at the remaining calls to ScGlobal::GetAutoFormat, in
sc/source/core/data/table4.cxx
sc/source/ui/docshell/docfunc.cxx
sc/source/ui/unoobj/afmtuno.cxx
sc/source/ui/unoobj/cellsuno.cxx
and check whether not creating a fresh ScAutoFormat is OK for them, or
whether they should be calls to GetOrCreateAutoFormat after all (and the
confusing null-checks removed).
Stephan
>From 9ff9055ae635ac2224adfc6601f27561956a5e74 Mon Sep 17 00:00:00 2001
From: Stephan Bergmann <sberg...@redhat.com>
Date: Fri, 6 Jan 2012 18:55:28 +0100
Subject: [PATCH] ScGlobal::GetAutoFormat not always required to create fresh
instance.
...at least in ~ScAutoFormatObj it appears unnecessary and can lead to
crashes during Desktop::DeregisterServices (when ScGlobal::ppRscString
is already null and ScAutoFormat ctor calls ScGlobal::GetRscString).
Therefore split GetAutoFormat in two, GetOrCreateAutoFormat for cases
that apparently need a non-null return and GetAutoFormat for those that
are (hopefully) also OK with a null return.
---
sc/inc/global.hxx | 1 +
sc/source/core/data/global.cxx | 5 +++++
sc/source/ui/miscdlgs/scuiautofmt.cxx | 4 ++--
sc/source/ui/unoobj/afmtuno.cxx | 3 +--
sc/source/ui/view/cellsh3.cxx | 4 ++--
5 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx
index a810400..ac10094 100644
--- a/sc/inc/global.hxx
+++ b/sc/inc/global.hxx
@@ -562,6 +562,7 @@ public:
SC_DLLPUBLIC static const SvxSearchItem& GetSearchItem();
SC_DLLPUBLIC static void SetSearchItem( const SvxSearchItem& rNew );
SC_DLLPUBLIC static ScAutoFormat* GetAutoFormat();
+ SC_DLLPUBLIC static ScAutoFormat* GetOrCreateAutoFormat();
static void ClearAutoFormat(); //BugId 54209
static FuncCollection* GetFuncCollection();
SC_DLLPUBLIC static ScUnoAddInCollection* GetAddInCollection();
diff --git a/sc/source/core/data/global.cxx b/sc/source/core/data/global.cxx
index 6de3782..c43a853 100644
--- a/sc/source/core/data/global.cxx
+++ b/sc/source/core/data/global.cxx
@@ -299,6 +299,11 @@ void ScGlobal::ClearAutoFormat()
ScAutoFormat* ScGlobal::GetAutoFormat()
{
+ return pAutoFormat;
+}
+
+ScAutoFormat* ScGlobal::GetOrCreateAutoFormat()
+{
if ( !pAutoFormat )
{
pAutoFormat = new ScAutoFormat;
diff --git a/sc/source/ui/miscdlgs/scuiautofmt.cxx b/sc/source/ui/miscdlgs/scuiautofmt.cxx
index d51b420..9466a4b 100644
--- a/sc/source/ui/miscdlgs/scuiautofmt.cxx
+++ b/sc/source/ui/miscdlgs/scuiautofmt.cxx
@@ -194,7 +194,7 @@ IMPL_LINK( ScAutoFormatDlg, CloseHdl, PushButton *, pBtn )
if ( pBtn == &aBtnOk || pBtn == &aBtnCancel )
{
if ( bCoreDataChanged )
- ScGlobal::GetAutoFormat()->Save();
+ ScGlobal::GetOrCreateAutoFormat()->Save();
EndDialog( (pBtn == &aBtnOk) ? RET_OK : RET_CANCEL );
}
@@ -206,7 +206,7 @@ IMPL_LINK( ScAutoFormatDlg, CloseHdl, PushButton *, pBtn )
IMPL_LINK_INLINE_START( ScAutoFormatDlg, DblClkHdl, void *, EMPTYARG )
{
if ( bCoreDataChanged )
- ScGlobal::GetAutoFormat()->Save();
+ ScGlobal::GetOrCreateAutoFormat()->Save();
EndDialog( RET_OK );
return 0;
diff --git a/sc/source/ui/unoobj/afmtuno.cxx b/sc/source/ui/unoobj/afmtuno.cxx
index f9dc03d..9a28b47 100644
--- a/sc/source/ui/unoobj/afmtuno.cxx
+++ b/sc/source/ui/unoobj/afmtuno.cxx
@@ -221,8 +221,7 @@ uno::Sequence<rtl::OUString> ScAutoFormatsObj::getSupportedServiceNames_Static()
ScAutoFormatObj* ScAutoFormatsObj::GetObjectByIndex_Impl(sal_uInt16 nIndex)
{
- ScAutoFormat* pFormats = ScGlobal::GetAutoFormat();
- if (pFormats && nIndex < pFormats->GetCount())
+ if (nIndex < ScGlobal::GetOrCreateAutoFormat()->GetCount())
return new ScAutoFormatObj(nIndex);
return NULL; // falscher Index
diff --git a/sc/source/ui/view/cellsh3.cxx b/sc/source/ui/view/cellsh3.cxx
index 19111c8..a9950c8 100644
--- a/sc/source/ui/view/cellsh3.cxx
+++ b/sc/source/ui/view/cellsh3.cxx
@@ -816,7 +816,7 @@ void ScCellShell::Execute( SfxRequest& rReq )
if ( pReqArgs )
{
const SfxStringItem& rNameItem = (const SfxStringItem&)pReqArgs->Get( SID_AUTOFORMAT );
- ScAutoFormat* pFormat = ScGlobal::GetAutoFormat();
+ ScAutoFormat* pFormat = ScGlobal::GetOrCreateAutoFormat();
sal_uInt16 nIndex = pFormat->FindIndexPerName( rNameItem.GetValue() );
pTabViewShell->AutoFormat( nIndex );
@@ -831,7 +831,7 @@ void ScCellShell::Execute( SfxRequest& rReq )
ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
OSL_ENSURE(pFact, "ScAbstractFactory create fail!");
- AbstractScAutoFormatDlg* pDlg = pFact->CreateScAutoFormatDlg( pDlgParent, ScGlobal::GetAutoFormat(), pNewEntry,GetViewData()->GetDocument(), RID_SCDLG_AUTOFORMAT );
+ AbstractScAutoFormatDlg* pDlg = pFact->CreateScAutoFormatDlg( pDlgParent, ScGlobal::GetOrCreateAutoFormat(), pNewEntry,GetViewData()->GetDocument(), RID_SCDLG_AUTOFORMAT );
OSL_ENSURE(pDlg, "Dialog create fail!");
if ( pDlg->Execute() == RET_OK )
--
1.7.7.4
_______________________________________________
LibreOffice mailing list
LibreOffice@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice