From 268f7ef41c09c537e1656f1653b757aedf76d788 Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Mon, 11 Nov 2013 12:24:58 +0100 Subject: Destroy SfxAllItemSet before calling framework::Desktop::terminate ...otherwise running e.g. "soffice slot:5410" would crash with > Invalid read of size 8 > at 0x712DCCC: SfxItemSet::~SfxItemSet() (svl/source/items/itemset.cxx:317) > by 0x65B4990: SfxAllItemSet::~SfxAllItemSet() (include/svl/itemset.hxx:166) > by 0x65B2CC4: SfxAllItemSet::~SfxAllItemSet() (include/svl/itemset.hxx:166) > by 0x674CD94: SfxDispatchController_Impl::dispatch(com::sun::star::util::URL const&, com::sun::star::uno::Sequence const&, com::sun::star::uno::Reference const&) (sfx2/source/control/unoctitm.cxx:784) > by 0x674CF46: SfxOfficeDispatch::dispatchWithNotification(com::sun::star::util::URL const&, com::sun::star::uno::Sequence const&, com::sun::star::uno::Reference const&) (sfx2/source/control/unoctitm.cxx:376) > by 0x674D03E: non-virtual thunk to SfxOfficeDispatch::dispatchWithNotification(com::sun::star::util::URL const&, com::sun::star::uno::Sequence const&, com::sun::star::uno::Reference const&) (sfx2/source/control/unoctitm.cxx:378) > by 0x4F21028: desktop::DispatchWatcher::executeDispatchRequests(std::__debug::vector > const&, bool) (desktop/source/app/dispatchwatcher.cxx:581) > by 0x4F2CDB3: desktop::OfficeIPCThread::ExecuteCmdLineRequests(desktop::ProcessDocumentsRequest&) (desktop/source/app/officeipcthread.cxx:1061) > by 0x4EE3159: desktop::Desktop::OpenClients() (desktop/source/app/app.cxx:2493) > by 0x4EE14E7: desktop::Desktop::OpenClients_Impl(void*) (desktop/source/app/app.cxx:2012) > by 0x4EE0127: desktop::Desktop::LinkStubOpenClients_Impl(void*, void*) (desktop/source/app/app.cxx:2007) > by 0x927B9E6: Link::Call(void*) const (include/tools/link.hxx:123) > by 0x999AD8F: ImplHandleUserEvent(ImplSVEvent*) (vcl/source/window/winproc.cxx:1976) > by 0x9997E64: ImplWindowFrameProc(Window*, SalFrame*, unsigned short, void const*) (vcl/source/window/winproc.cxx:2591) > by 0x99ADCFC: SalFrame::CallCallback(unsigned short, void const*) const (vcl/inc/salframe.hxx:243) > by 0x99ACD47: SalGenericDisplay::DispatchInternalEvent() (vcl/generic/app/gendisp.cxx:91) > by 0x1783C027: GtkData::userEventFn(void*) (vcl/unx/gtk/app/gtkdata.cxx:935) > by 0x1783C13D: call_userEventFn(void*) (vcl/unx/gtk/app/gtkdata.cxx:945) > by 0x37B6847E05: g_main_context_dispatch (usr/src/debug/glib-2.36.3/glib/gmain.c:3054) > by 0x37B6848157: g_main_context_iterate.isra.22 (usr/src/debug/glib-2.36.3/glib/gmain.c:3701) > by 0x37B68481FB: g_main_context_iteration (usr/src/debug/glib-2.36.3/glib/gmain.c:3762) > by 0x1783AC3F: GtkData::Yield(bool, bool) (vcl/unx/gtk/app/gtkdata.cxx:576) > by 0x1783FEF6: GtkInstance::Yield(bool, bool) (vcl/unx/gtk/app/gtkinst.cxx:425) > by 0x9299F40: ImplYield(bool, bool) (vcl/source/app/svapp.cxx:364) > by 0x9295B52: Application::Yield() (vcl/source/app/svapp.cxx:396) > by 0x9295B1F: Application::Execute() (vcl/source/app/svapp.cxx:345) > by 0x4EDE2C9: desktop::Desktop::Main() (desktop/source/app/app.cxx:1715) > by 0x92A6397: ImplSVMain() (vcl/source/app/svmain.cxx:162) > by 0x92A7B55: SVMain() (vcl/source/app/svmain.cxx:198) > by 0x4F35980: soffice_main (desktop/source/app/sofficemain.cxx:85) > by 0x40098C: sal_main (desktop/source/app/main.c:48) > by 0x400966: main (desktop/source/app/main.c:47) > Address 0x1d719700 is 0 bytes inside a block of size 32 free'd > at 0x4A078DE: operator delete(void*) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) > by 0x6A02EA1: CntItemPool::~CntItemPool() (sfx2/source/explorer/nochaos.cxx:123) > by 0x6A02C85: CntItemPool::Release() (sfx2/source/explorer/nochaos.cxx:154) > by 0x6A02BF8: NoChaos::ReleaseItemPool() (sfx2/source/explorer/nochaos.cxx:89) > by 0x65E1A31: SfxApplication::Deinitialize() (sfx2/source/appl/appquit.cxx:147) > by 0x65A29B0: SfxApplication::~SfxApplication() (sfx2/source/appl/app.cxx:242) > by 0x65A2828: SfxApplication::~SfxApplication() (sfx2/source/appl/app.cxx:223) > by 0x65C021C: SfxTerminateListener_Impl::notifyTermination(com::sun::star::lang::EventObject const&) (sfx2/source/appl/appinit.cxx:121) > by 0x65C033E: non-virtual thunk to SfxTerminateListener_Impl::notifyTermination(com::sun::star::lang::EventObject const&) (sfx2/source/appl/appinit.cxx:123) > by 0x1F176DD2: framework::Desktop::terminate() (framework/source/services/desktop.cxx:353) > by 0x1F177E1B: non-virtual thunk to framework::Desktop::terminate() (framework/source/services/desktop.cxx:357) > by 0x4F217FD: desktop::DispatchWatcher::dispatchFinished(com::sun::star::frame::DispatchResultEvent const&) (desktop/source/app/dispatchwatcher.cxx:637) > by 0x4F2190E: non-virtual thunk to desktop::DispatchWatcher::dispatchFinished(com::sun::star::frame::DispatchResultEvent const&) (desktop/source/app/dispatchwatcher.cxx:640) > by 0x674CD77: SfxDispatchController_Impl::dispatch(com::sun::star::util::URL const&, com::sun::star::uno::Sequence const&, com::sun::star::uno::Reference const&) (sfx2/source/control/unoctitm.cxx:782) > ... Change-Id: I6b4fb9b6f0d2afc9caecf3dd5355d11edb6abbe8 --- sfx2/source/control/unoctitm.cxx | 140 +++++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 66 deletions(-) (limited to 'sfx2') diff --git a/sfx2/source/control/unoctitm.cxx b/sfx2/source/control/unoctitm.cxx index 496e6b961d56..66d54208fd86 100644 --- a/sfx2/source/control/unoctitm.cxx +++ b/sfx2/source/control/unoctitm.cxx @@ -677,89 +677,97 @@ void SAL_CALL SfxDispatchController_Impl::dispatch( const ::com::sun::star::util if (pViewFrame) xFrameRef = pViewFrame->GetFrame().GetFrameInterface(); } - SfxAllItemSet aInternalSet( SFX_APP()->GetPool() ); - if (xFrameRef.is()) // an empty set is no problem ... but an empty frame reference can be a problem ! - aInternalSet.Put( SfxUnoFrameItem( SID_FILLFRAME, xFrameRef ) ); sal_Bool bSuccess = sal_False; const SfxPoolItem* pItem = NULL; - SfxShell* pShell( 0 ); - // #i102619# Retrieve metric from shell before execution - the shell could be destroyed after execution SfxMapUnit eMapUnit( SFX_MAPUNIT_100TH_MM ); - if ( pDispatcher->GetBindings() ) + + // Extra scope so that aInternalSet is destroyed before + // rListener->dispatchFinished potentially calls + // framework::Desktop::terminate -> SfxApplication::Deinitialize -> + // ~CntItemPool: { - if ( !pDispatcher->IsLocked( GetId() ) ) + SfxAllItemSet aInternalSet( SFX_APP()->GetPool() ); + if (xFrameRef.is()) // an empty set is no problem ... but an empty frame reference can be a problem ! + aInternalSet.Put( SfxUnoFrameItem( SID_FILLFRAME, xFrameRef ) ); + + SfxShell* pShell( 0 ); + // #i102619# Retrieve metric from shell before execution - the shell could be destroyed after execution + if ( pDispatcher->GetBindings() ) { - const SfxSlot *pSlot = 0; - if ( pDispatcher->GetShellAndSlot_Impl( GetId(), &pShell, &pSlot, sal_False, - SFX_CALLMODE_MODAL==(nCall&SFX_CALLMODE_MODAL), sal_False ) ) + if ( !pDispatcher->IsLocked( GetId() ) ) { - if ( bMasterSlave ) - { - // Extract slave command and add argument to the args list. Master slot MUST - // have a argument that has the same name as the master slot and type is SfxStringItem. - sal_Int32 nIndex = lNewArgs.getLength(); - lNewArgs.realloc( nIndex+1 ); - lNewArgs[nIndex].Name = OUString::createFromAscii( pSlot->pUnoName ); - lNewArgs[nIndex].Value = makeAny( SfxDispatchController_Impl::getSlaveCommand( aDispatchURL )); - } - - eMapUnit = GetCoreMetric( pShell->GetPool(), GetId() ); - boost::scoped_ptr xSet(new SfxAllItemSet(pShell->GetPool())); - TransformParameters(GetId(), lNewArgs, *xSet, pSlot); - if (xSet->Count()) - { - // execute with arguments - call directly - pItem = pDispatcher->Execute(GetId(), nCall, xSet.get(), &aInternalSet, nModifier); - bSuccess = (pItem != NULL); - } - else + const SfxSlot *pSlot = 0; + if ( pDispatcher->GetShellAndSlot_Impl( GetId(), &pShell, &pSlot, sal_False, + SFX_CALLMODE_MODAL==(nCall&SFX_CALLMODE_MODAL), sal_False ) ) { - // Be sure to delete this before we send a dispatch - // request, which will destroy the current shell. - xSet.reset(); - - // execute using bindings, enables support for toggle/enum etc. - SfxRequest aReq( GetId(), nCall, pShell->GetPool() ); - aReq.SetModifier( nModifier ); - aReq.SetInternalArgs_Impl(aInternalSet); - pDispatcher->GetBindings()->Execute_Impl( aReq, pSlot, pShell ); - pItem = aReq.GetReturnValue(); - bSuccess = aReq.IsDone() || pItem != NULL; + if ( bMasterSlave ) + { + // Extract slave command and add argument to the args list. Master slot MUST + // have a argument that has the same name as the master slot and type is SfxStringItem. + sal_Int32 nIndex = lNewArgs.getLength(); + lNewArgs.realloc( nIndex+1 ); + lNewArgs[nIndex].Name = OUString::createFromAscii( pSlot->pUnoName ); + lNewArgs[nIndex].Value = makeAny( SfxDispatchController_Impl::getSlaveCommand( aDispatchURL )); + } + + eMapUnit = GetCoreMetric( pShell->GetPool(), GetId() ); + boost::scoped_ptr xSet(new SfxAllItemSet(pShell->GetPool())); + TransformParameters(GetId(), lNewArgs, *xSet, pSlot); + if (xSet->Count()) + { + // execute with arguments - call directly + pItem = pDispatcher->Execute(GetId(), nCall, xSet.get(), &aInternalSet, nModifier); + bSuccess = (pItem != NULL); + } + else + { + // Be sure to delete this before we send a dispatch + // request, which will destroy the current shell. + xSet.reset(); + + // execute using bindings, enables support for toggle/enum etc. + SfxRequest aReq( GetId(), nCall, pShell->GetPool() ); + aReq.SetModifier( nModifier ); + aReq.SetInternalArgs_Impl(aInternalSet); + pDispatcher->GetBindings()->Execute_Impl( aReq, pSlot, pShell ); + pItem = aReq.GetReturnValue(); + bSuccess = aReq.IsDone() || pItem != NULL; + } } - } #ifdef DBG_UTIL - else - DBG_WARNING("MacroPlayer: Unknown slot dispatched!"); + else + DBG_WARNING("MacroPlayer: Unknown slot dispatched!"); #endif + } } - } - else - { - eMapUnit = GetCoreMetric( SFX_APP()->GetPool(), GetId() ); - // AppDispatcher - SfxAllItemSet aSet( SFX_APP()->GetPool() ); - TransformParameters( GetId(), lNewArgs, aSet ); - - if ( aSet.Count() ) - pItem = pDispatcher->Execute( GetId(), nCall, &aSet, &aInternalSet, nModifier ); else - // SfxRequests take empty sets as argument sets, GetArgs() returning non-zero! - pItem = pDispatcher->Execute( GetId(), nCall, 0, &aInternalSet, nModifier ); - - // no bindings, no invalidate ( usually done in SfxDispatcher::Call_Impl()! ) - if ( SfxApplication::Get() ) { - SfxDispatcher* pAppDispat = SFX_APP()->GetAppDispatcher_Impl(); - if ( pAppDispat ) + eMapUnit = GetCoreMetric( SFX_APP()->GetPool(), GetId() ); + // AppDispatcher + SfxAllItemSet aSet( SFX_APP()->GetPool() ); + TransformParameters( GetId(), lNewArgs, aSet ); + + if ( aSet.Count() ) + pItem = pDispatcher->Execute( GetId(), nCall, &aSet, &aInternalSet, nModifier ); + else + // SfxRequests take empty sets as argument sets, GetArgs() returning non-zero! + pItem = pDispatcher->Execute( GetId(), nCall, 0, &aInternalSet, nModifier ); + + // no bindings, no invalidate ( usually done in SfxDispatcher::Call_Impl()! ) + if ( SfxApplication::Get() ) { - const SfxPoolItem* pState=0; - SfxItemState eState = pDispatcher->QueryState( GetId(), pState ); - StateChanged( GetId(), eState, pState ); + SfxDispatcher* pAppDispat = SFX_APP()->GetAppDispatcher_Impl(); + if ( pAppDispat ) + { + const SfxPoolItem* pState=0; + SfxItemState eState = pDispatcher->QueryState( GetId(), pState ); + StateChanged( GetId(), eState, pState ); + } } - } - bSuccess = (pItem != NULL); + bSuccess = (pItem != NULL); + } } if ( rListener.is() ) -- cgit