summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2019-12-28 03:49:16 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2019-12-29 15:46:16 +0100
commit8cce131dcc1803ac95f3079098be767662fcca09 (patch)
tree6a981ec6eca66a2cd3482768c19f32847713a7de
parent06cbfe71c77cfd61b747b7f80dee37e59cff0118 (diff)
Avoid crash in shutdown when accessing already destroyed BASIC_DLL
... in ImplRepository::~ImplRepository. Running on Windows: make UITest_manual_tests UITEST_TEST_NAME=calc.ManualCalcTests.test_cell_recalc fails: ... Execution time for calc.ManualCalcTests.test_cell_recalc: 8.876 tearDown: calling terminate()... ...done ERROR ====================================================================== ERROR: test_cell_recalc (calc.ManualCalcTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\lo\src\core\uitest\uitest\framework.py", line 46, in tearDown self.connection.tearDown() File "C:\lo\src\core\uitest\libreoffice\connection.py", line 178, in tearDown self.connection.tearDown() File "C:\lo\src\core\uitest\libreoffice\connection.py", line 138, in tearDown raise Exception("Exit status indicates failure: " + str(ret)) Exception: Exit status indicates failure: 3221225477 ---------------------------------------------------------------------- Ran 1 test in 131.616s FAILED (errors=1) Tests run: 1 Tests failed: 0 Tests errors: 1 Tests skipped: 0 The call stack at the point of failure is sblo.dll!std::unique_ptr<SbxAppData,std::default_delete<SbxAppData>>::operator*() Line 1886 sblo.dll!GetSbxData_Impl() Line 110 sblo.dll!SbxBase::RemoveFactory(const SbxFactory * pFac) Line 122 sblo.dll!StarBASIC::~StarBASIC() Line 964 sblo.dll!StarBASIC::`vbase destructor'() sblo.dll!StarBASIC::`vector deleting destructor'(unsigned int) tllo.dll!SvRefBase::ReleaseRef() Line 163 sblo.dll!tools::SvRef<StarBASIC>::~SvRef<StarBASIC>() Line 56 sblo.dll!BasicLibInfo::~BasicLibInfo() sblo.dll!BasicLibInfo::`scalar deleting destructor'(unsigned int) sblo.dll!std::default_delete<BasicLibInfo>::operator()(BasicLibInfo * _Ptr) Line 1765 sblo.dll!std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>>::~unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>>() Line 1875 sblo.dll!std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>>::`scalar deleting destructor'(unsigned int) sblo.dll!std::_Default_allocator_traits<std::allocator<std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>>>>::destroy<std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>>>(std::allocator<std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>>> & __formal, std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>> * const _Ptr) Line 677 sblo.dll!std::_Destroy_range<std::allocator<std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>>>>(std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>> * _First, std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>> * const _Last, std::allocator<std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>>> & _Al) Line 951 sblo.dll!std::vector<std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>>,std::allocator<std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>>>>::_Destroy(std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>> * _First, std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>> * _Last) Line 1616 sblo.dll!std::vector<std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>>,std::allocator<std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>>>>::_Tidy() Line 1698 sblo.dll!std::vector<std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>>,std::allocator<std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>>>>::~vector<std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>>,std::allocator<std::unique_ptr<BasicLibInfo,std::default_delete<BasicLibInfo>>>>() Line 674 sblo.dll!BasicManagerImpl::~BasicManagerImpl() sblo.dll!BasicManagerImpl::`scalar deleting destructor'(unsigned int) sblo.dll!std::default_delete<BasicManagerImpl>::operator()(BasicManagerImpl * _Ptr) Line 1765 sblo.dll!std::unique_ptr<BasicManagerImpl,std::default_delete<BasicManagerImpl>>::~unique_ptr<BasicManagerImpl,std::default_delete<BasicManagerImpl>>() Line 1875 sblo.dll!BasicManager::~BasicManager() Line 824 sblo.dll!BasicManager::`vector deleting destructor'(unsigned int) sblo.dll!std::default_delete<BasicManager>::operator()(BasicManager * _Ptr) Line 1765 sblo.dll!std::unique_ptr<BasicManager,std::default_delete<BasicManager>>::~unique_ptr<BasicManager,std::default_delete<BasicManager>>() Line 1875 sblo.dll!std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>::~pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>() sblo.dll!std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>::`scalar deleting destructor'(unsigned int) sblo.dll!std::_Default_allocator_traits<std::allocator<std::_Tree_node<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>,void *>>>::destroy<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>>(std::allocator<std::_Tree_node<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>,void *>> & __formal, std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>> * const _Ptr) Line 677 sblo.dll!std::_Tree_node<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>,void *>::_Freenode<std::allocator<std::_Tree_node<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>,void *>>>(std::allocator<std::_Tree_node<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>,void *>> & _Al, std::_Tree_node<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>,void *> * _Ptr) Line 379 sblo.dll!std::_Tree<std::_Tmap_traits<com::sun::star::uno::Reference<com::sun::star::uno::XInterface>,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>,std::less<com::sun::star::uno::Reference<com::sun::star::uno::XInterface>>,std::allocator<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>>,0>>::_Erase_unchecked(std::_Tree_unchecked_const_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>>>,std::_Iterator_base0> _Where) Line 1389 sblo.dll!std::_Tree<std::_Tmap_traits<com::sun::star::uno::Reference<com::sun::star::uno::XInterface>,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>,std::less<com::sun::star::uno::Reference<com::sun::star::uno::XInterface>>,std::allocator<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>>,0>>::erase<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>>>>,void>(std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>>>> _Where) Line 1417 sblo.dll!basic::ImplRepository::Notify(SfxBroadcaster & _rBC, const SfxHint & _rHint) Line 580 svllo.dll!SfxBroadcaster::Broadcast(const SfxHint & rHint) Line 50 sblo.dll!BasicManager::~BasicManager() Line 823 sblo.dll!BasicManager::`vector deleting destructor'(unsigned int) sblo.dll!std::default_delete<BasicManager>::operator()(BasicManager * _Ptr) Line 1765 sblo.dll!std::unique_ptr<BasicManager,std::default_delete<BasicManager>>::~unique_ptr<BasicManager,std::default_delete<BasicManager>>() Line 1875 sblo.dll!std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>::~pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>() sblo.dll!std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>::`scalar deleting destructor'(unsigned int) sblo.dll!std::_Default_allocator_traits<std::allocator<std::_Tree_node<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>,void *>>>::destroy<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>>(std::allocator<std::_Tree_node<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>,void *>> & __formal, std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>> * const _Ptr) Line 677 sblo.dll!std::_Tree_node<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>,void *>::_Freenode<std::allocator<std::_Tree_node<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>,void *>>>(std::allocator<std::_Tree_node<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>,void *>> & _Al, std::_Tree_node<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>,void *> * _Ptr) Line 379 sblo.dll!std::_Tree_val<std::_Tree_simple_types<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>>>::_Erase_tree<std::allocator<std::_Tree_node<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>,void *>>>(std::allocator<std::_Tree_node<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>,void *>> & _Al, std::_Tree_node<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>,void *> * _Rootnode) Line 745 sblo.dll!std::_Tree_val<std::_Tree_simple_types<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>>>::_Erase_head<std::allocator<std::_Tree_node<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>,void *>>>(std::allocator<std::_Tree_node<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>,void *>> & _Al) Line 753 sblo.dll!std::_Tree<std::_Tmap_traits<com::sun::star::uno::Reference<com::sun::star::uno::XInterface>,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>,std::less<com::sun::star::uno::Reference<com::sun::star::uno::XInterface>>,std::allocator<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>>,0>>::~_Tree<std::_Tmap_traits<com::sun::star::uno::Reference<com::sun::star::uno::XInterface>,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>,std::less<com::sun::star::uno::Reference<com::sun::star::uno::XInterface>>,std::allocator<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>>,0>>() Line 1191 sblo.dll!std::map<com::sun::star::uno::Reference<com::sun::star::uno::XInterface>,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>,std::less<com::sun::star::uno::Reference<com::sun::star::uno::XInterface>>,std::allocator<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>>>::~map<com::sun::star::uno::Reference<com::sun::star::uno::XInterface>,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>,std::less<com::sun::star::uno::Reference<com::sun::star::uno::XInterface>>,std::allocator<std::pair<com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const ,std::unique_ptr<BasicManager,std::default_delete<BasicManager>>>>>() sblo.dll!basic::ImplRepository::~ImplRepository() sblo.dll!`basic::ImplRepository::Instance'::`2'::`dynamic atexit destructor for 'repository''() ucrtbased.dll!_execute_onexit_table::__l2::<lambda>() Line 206 ucrtbased.dll!__crt_seh_guarded_call<int>::operator()<void <lambda>(void),int <lambda>(void) &,void <lambda>(void)>(__acrt_lock_and_call::__l2::void <lambda>(void) && setup, _execute_onexit_table::__l2::int <lambda>(void) & action, __acrt_lock_and_call::__l2::void <lambda>(void) && cleanup) Line 204 ucrtbased.dll!__acrt_lock_and_call<int <lambda>(void)>(const __acrt_lock_id lock_id, _execute_onexit_table::__l2::int <lambda>(void) && action) Line 975 ucrtbased.dll!_execute_onexit_table(_onexit_table_t * table) Line 231 sblo.dll!__scrt_dllmain_uninitialize_c() Line 399 sblo.dll!dllmain_crt_process_detach(const bool is_terminating) Line 182 sblo.dll!dllmain_crt_dispatch(HINSTANCE__ * const instance, const unsigned long reason, void * const reserved) Line 220 sblo.dll!dllmain_dispatch(HINSTANCE__ * const instance, const unsigned long reason, void * const reserved) Line 293 sblo.dll!_DllMainCRTStartup(HINSTANCE__ * const instance, const unsigned long reason, void * const reserved) Line 335 ntdll.dll!LdrpCallInitRoutine() ntdll.dll!LdrShutdownProcess() ntdll.dll!RtlExitUserProcess() kernel32.dll!ExitProcessImplementation() ucrtbased.dll!exit_or_terminate_process(const unsigned int return_code) Line 144 ucrtbased.dll!common_exit(const int return_code, const _crt_exit_cleanup_mode cleanup_mode, const _crt_exit_return_mode return_mode) Line 282 ucrtbased.dll!exit(int return_code) Line 294 soffice.bin!__scrt_common_main_seh() Line 297 soffice.bin!__scrt_common_main() Line 331 soffice.bin!mainCRTStartup() Line 17 kernel32.dll!BaseThreadInitThunk() ntdll.dll!RtlUserThreadStart() Two problems here: 1. Deleting a function-local static ImplRepository object happens after BASIC_DLL destruction either in SfxApplication::~SfxApplication or in MacroSnippet::~MacroSnippet, so BasicManager dtor indirectly trying to access BASIC_DLL segfaults. 2. Implicit clearing of m_aStore in ImplRepository dtor calls dtors of owned BasicManager objects, which in turn notify parent ImplRepository, which again deletes the objects. This change limits lifetime of ImplRepository object with SbxAppData in BASIC_DLL, and avoids "owned BasicManager is deleting" notifications in its dtor. In dbaccess_complex test, ODatabaseContext accesses ImplRepository instance independently of SfxAppData_Impl lifetime: the latter is created before the former is created (and accesses ImplRepository instance first time), and destroyed before the former is destroyed (and accesses ImplRepository last time). So BASIC_DLL lifetime made ref-counted, to allow correct sharing of common instance between objects with independent lifetime. See also commit 3ebf6a090b227c0097ff8668fe023e7bdbdadc5d. Change-Id: I2ca36a87ddaf669557b3c3c7678e3d74aae66cce Reviewed-on: https://gerrit.libreoffice.org/c/core/+/85892 Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com> Tested-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r--basic/inc/sbxbase.hxx1
-rw-r--r--basic/source/basmgr/basicmanagerrepository.cxx20
-rw-r--r--basic/source/runtime/basrdll.cxx53
-rw-r--r--basic/source/sbx/sbxbase.cxx3
-rw-r--r--dbaccess/source/core/inc/databasecontext.hxx10
-rw-r--r--include/basic/basrdll.hxx7
-rw-r--r--include/unotest/macros_test.hxx11
-rw-r--r--sfx2/source/appl/app.cxx7
-rw-r--r--sfx2/source/appl/appdata.cxx7
-rw-r--r--unotest/source/cpp/macros_test.cxx8
10 files changed, 92 insertions, 35 deletions
diff --git a/basic/inc/sbxbase.hxx b/basic/inc/sbxbase.hxx
index a4ea06678f27..269f6029a55a 100644
--- a/basic/inc/sbxbase.hxx
+++ b/basic/inc/sbxbase.hxx
@@ -40,6 +40,7 @@ struct SbxAppData
SbxVariableRef m_aGlobErr; // Global error object
std::vector<std::unique_ptr<SbxFactory>>
m_Factories;
+ tools::SvRef<SvRefBase> mrImplRepository;
// Pointer to Format()-Command helper class
std::unique_ptr<SbxBasicFormater> pBasicFormater;
diff --git a/basic/source/basmgr/basicmanagerrepository.cxx b/basic/source/basmgr/basicmanagerrepository.cxx
index 9116dbd382f1..01ca8759e145 100644
--- a/basic/source/basmgr/basicmanagerrepository.cxx
+++ b/basic/source/basmgr/basicmanagerrepository.cxx
@@ -22,6 +22,7 @@
#include <scriptcont.hxx>
#include <dlgcont.hxx>
#include <sbintern.hxx>
+#include <sbxbase.hxx>
#include <com/sun/star/document/XStorageBasedDocument.hpp>
#include <com/sun/star/document/XEmbeddedScripts.hpp>
@@ -62,10 +63,11 @@ namespace basic
typedef std::vector< BasicManagerCreationListener* > CreationListeners;
- class ImplRepository : public ::utl::OEventListenerAdapter, public SfxListener
+ class ImplRepository : public ::utl::OEventListenerAdapter, public SfxListener, public SvRefBase
{
private:
ImplRepository();
+ ~ImplRepository();
private:
BasicManagerStore m_aStore;
@@ -193,11 +195,23 @@ namespace basic
{
}
+ ImplRepository::~ImplRepository()
+ {
+ // Avoid double-delete of managers when they are destroyed in our dtor, and start notify us
+ for (auto& it : m_aStore)
+ EndListening(*it.second);
+ }
ImplRepository& ImplRepository::Instance()
{
- static ImplRepository repository;
- return repository;
+ tools::SvRef<SvRefBase>& repository = GetSbxData_Impl().mrImplRepository;
+ {
+ static osl::Mutex aMutex;
+ osl::MutexGuard aGuard(aMutex);
+ if (!repository)
+ repository = new ImplRepository;
+ }
+ return *static_cast<ImplRepository*>(repository.get());
}
BasicManager* ImplRepository::getDocumentBasicManager( const Reference< XModel >& _rxDocumentModel )
diff --git a/basic/source/runtime/basrdll.cxx b/basic/source/runtime/basrdll.cxx
index a3145f404979..9fd82145afd2 100644
--- a/basic/source/runtime/basrdll.cxx
+++ b/basic/source/runtime/basrdll.cxx
@@ -28,69 +28,80 @@
#include <sbxbase.hxx>
#include <config_features.h>
-struct BasicDLL::Impl
+namespace
+{
+struct BasicDLLImpl : public SvRefBase
{
bool bDebugMode;
bool bBreakEnabled;
std::unique_ptr<SbxAppData> xSbxAppData;
- Impl()
+ BasicDLLImpl()
: bDebugMode(false)
, bBreakEnabled(true)
, xSbxAppData(new SbxAppData)
{ }
-};
-
-namespace {
-BasicDLL * BASIC_DLL;
+ static BasicDLLImpl* BASIC_DLL;
+ static osl::Mutex& getMutex()
+ {
+ static osl::Mutex aMutex;
+ return aMutex;
+ }
+};
+BasicDLLImpl* BasicDLLImpl::BASIC_DLL = nullptr;
}
BasicDLL::BasicDLL()
- : m_xImpl(new Impl)
{
- BASIC_DLL = this;
+ osl::MutexGuard aGuard(BasicDLLImpl::getMutex());
+ if (!BasicDLLImpl::BASIC_DLL)
+ BasicDLLImpl::BASIC_DLL = new BasicDLLImpl;
+ m_xImpl = BasicDLLImpl::BASIC_DLL;
}
BasicDLL::~BasicDLL()
{
+ osl::MutexGuard aGuard(BasicDLLImpl::getMutex());
+ const bool bLastRef = m_xImpl->GetRefCount() == 1;
+ m_xImpl.clear();
+ // only reset BASIC_DLL after the object had been destroyed
+ if (bLastRef)
+ BasicDLLImpl::BASIC_DLL = nullptr;
}
void BasicDLL::EnableBreak( bool bEnable )
{
- BasicDLL* pThis = BASIC_DLL;
- DBG_ASSERT( pThis, "BasicDLL::EnableBreak: No instance yet!" );
- if ( pThis )
+ DBG_ASSERT( BasicDLLImpl::BASIC_DLL, "BasicDLL::EnableBreak: No instance yet!" );
+ if (BasicDLLImpl::BASIC_DLL)
{
- pThis->m_xImpl->bBreakEnabled = bEnable;
+ BasicDLLImpl::BASIC_DLL->bBreakEnabled = bEnable;
}
}
void BasicDLL::SetDebugMode( bool bDebugMode )
{
- BasicDLL* pThis = BASIC_DLL;
- DBG_ASSERT( pThis, "BasicDLL::EnableBreak: No instance yet!" );
- if ( pThis )
+ DBG_ASSERT( BasicDLLImpl::BASIC_DLL, "BasicDLL::EnableBreak: No instance yet!" );
+ if (BasicDLLImpl::BASIC_DLL)
{
- pThis->m_xImpl->bDebugMode = bDebugMode;
+ BasicDLLImpl::BASIC_DLL->bDebugMode = bDebugMode;
}
}
void BasicDLL::BasicBreak()
{
- BasicDLL* pThis = BASIC_DLL;
- DBG_ASSERT( pThis, "BasicDLL::EnableBreak: No instance yet!" );
+ DBG_ASSERT( BasicDLLImpl::BASIC_DLL, "BasicDLL::EnableBreak: No instance yet!" );
#if HAVE_FEATURE_SCRIPTING
- if ( pThis )
+ if (BasicDLLImpl::BASIC_DLL)
{
// bJustStopping: if there's someone pressing STOP like crazy umpteen times,
// but the Basic doesn't stop early enough, the box might appear more often...
static bool bJustStopping = false;
if (StarBASIC::IsRunning() && !bJustStopping
- && (pThis->m_xImpl->bBreakEnabled || pThis->m_xImpl->bDebugMode))
+ && (BasicDLLImpl::BASIC_DLL->bBreakEnabled || BasicDLLImpl::BASIC_DLL->bDebugMode))
{
bJustStopping = true;
StarBASIC::Stop();
@@ -106,7 +117,7 @@ void BasicDLL::BasicBreak()
SbxAppData& GetSbxData_Impl()
{
- return *BASIC_DLL->m_xImpl->xSbxAppData;
+ return *BasicDLLImpl::BASIC_DLL->xSbxAppData;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basic/source/sbx/sbxbase.cxx b/basic/source/sbx/sbxbase.cxx
index d1b17d4fa288..431a5ae5e612 100644
--- a/basic/source/sbx/sbxbase.cxx
+++ b/basic/source/sbx/sbxbase.cxx
@@ -46,6 +46,9 @@ SbxAppData::~SbxAppData()
SolarMutexGuard g;
pBasicFormater.reset();
+ m_aGlobErr.clear();
+ // basic manager repository must be destroyed before factories
+ mrImplRepository.clear();
m_Factories.clear();
}
diff --git a/dbaccess/source/core/inc/databasecontext.hxx b/dbaccess/source/core/inc/databasecontext.hxx
index 19c59a953f9d..6f5c2cb19d55 100644
--- a/dbaccess/source/core/inc/databasecontext.hxx
+++ b/dbaccess/source/core/inc/databasecontext.hxx
@@ -22,6 +22,8 @@
#include <sal/config.h>
+#include <config_features.h>
+
#include <map>
#include "ModelImpl.hxx"
@@ -41,6 +43,10 @@
#include <com/sun/star/uno/XNamingService.hpp>
#include <com/sun/star/uno/XAggregation.hpp>
+#if HAVE_FEATURE_SCRIPTING
+#include <basic/basrdll.hxx>
+#endif
+
#include <basic/basicmanagerrepository.hxx>
#include <cppuhelper/compbase.hxx>
#include <cppuhelper/interfacecontainer.hxx>
@@ -85,6 +91,10 @@ private:
css::uno::Reference< css::uno::XInterface >
impl_createNewDataSource();
+#if HAVE_FEATURE_SCRIPTING
+ BasicDLL m_aBasicDLL;
+#endif
+
protected:
::osl::Mutex m_aMutex;
css::uno::Reference< css::uno::XComponentContext >
diff --git a/include/basic/basrdll.hxx b/include/basic/basrdll.hxx
index e4e97ae65dbc..53768deb5760 100644
--- a/include/basic/basrdll.hxx
+++ b/include/basic/basrdll.hxx
@@ -21,13 +21,12 @@
#define INCLUDED_BASIC_BASRDLL_HXX
#include <basic/basicdllapi.h>
-#include <memory>
+#include <tools/ref.hxx>
class BASIC_DLLPUBLIC BasicDLL
{
-public:
- struct Impl;
- std::unique_ptr<Impl> m_xImpl;
+private:
+ tools::SvRef<SvRefBase> m_xImpl;
public:
BasicDLL();
diff --git a/include/unotest/macros_test.hxx b/include/unotest/macros_test.hxx
index 6ec5c25167df..4dcf9427fbf9 100644
--- a/include/unotest/macros_test.hxx
+++ b/include/unotest/macros_test.hxx
@@ -10,6 +10,9 @@
#ifndef INCLUDED_UNOTEST_MACROS_TEST_HXX
#define INCLUDED_UNOTEST_MACROS_TEST_HXX
+#include <sal/config.h>
+
+#include <memory>
#include <rtl/ustring.hxx>
#include <unotest/detail/unotestdllapi.hxx>
@@ -22,16 +25,24 @@ struct TestMacroInfo
OUString sMacroUrl;
};
+class BasicDLL;
+
namespace unotest {
class OOO_DLLPUBLIC_UNOTEST MacrosTest
{
public:
+ MacrosTest();
+ ~MacrosTest();
+
css::uno::Reference< css::lang::XComponent > loadFromDesktop(const OUString& rURL, const OUString& rDocService = OUString(),
const css::uno::Sequence<css::beans::PropertyValue>& rExtra_args = css::uno::Sequence<css::beans::PropertyValue>() );
protected:
css::uno::Reference< css::frame::XDesktop2> mxDesktop;
+
+private:
+ std::unique_ptr<BasicDLL> mpDll;
};
}
diff --git a/sfx2/source/appl/app.cxx b/sfx2/source/appl/app.cxx
index fafddce19064..c09b415825f6 100644
--- a/sfx2/source/appl/app.cxx
+++ b/sfx2/source/appl/app.cxx
@@ -24,7 +24,6 @@
#include <sfx2/app.hxx>
#include <sfx2/frame.hxx>
-#include <basic/basrdll.hxx>
#include <basic/sberrors.hxx>
#include <tools/svlibrary.h>
@@ -65,8 +64,6 @@ using namespace ::com::sun::star;
static SfxApplication* g_pSfxApplication = nullptr;
-static BasicDLL* pBasic = nullptr;
-
#if HAVE_FEATURE_DESKTOP
static SfxHelp* pSfxHelp = nullptr;
#endif
@@ -160,8 +157,6 @@ SfxApplication::SfxApplication()
pSfxHelp = new SfxHelp;
#endif
- pBasic = new BasicDLL;
-
#if HAVE_FEATURE_SCRIPTING
StarBASIC::SetGlobalErrorHdl( LINK( this, SfxApplication, GlobalBasicErrorHdl_Impl ) );
#endif
@@ -190,8 +185,6 @@ SfxApplication::~SfxApplication()
if ( !pImpl->bDowning )
Deinitialize();
- delete pBasic;
-
g_pSfxApplication = nullptr;
}
diff --git a/sfx2/source/appl/appdata.cxx b/sfx2/source/appl/appdata.cxx
index e37fc0e1e73e..1b74848f39cf 100644
--- a/sfx2/source/appl/appdata.cxx
+++ b/sfx2/source/appl/appdata.cxx
@@ -31,6 +31,7 @@
#include <basic/basicmanagerrepository.hxx>
#include <basic/basmgr.hxx>
+#include <basic/basrdll.hxx>
using ::basic::BasicManagerRepository;
using ::basic::BasicManagerCreationListener;
@@ -38,6 +39,8 @@ using ::com::sun::star::uno::Reference;
using ::com::sun::star::frame::XModel;
using ::com::sun::star::uno::XInterface;
+static BasicDLL* pBasic = nullptr;
+
class SfxBasicManagerCreationListener : public ::basic::BasicManagerCreationListener
{
private:
@@ -91,6 +94,8 @@ SfxAppData_Impl::SfxAppData_Impl()
, bInQuit( false )
{
+ pBasic = new BasicDLL;
+
#if HAVE_FEATURE_SCRIPTING
BasicManagerRepository::registerCreationListener( *pBasMgrListener );
#endif
@@ -105,6 +110,8 @@ SfxAppData_Impl::~SfxAppData_Impl()
BasicManagerRepository::revokeCreationListener( *pBasMgrListener );
pBasMgrListener.reset();
#endif
+
+ delete pBasic;
}
SfxDocumentTemplates* SfxAppData_Impl::GetDocumentTemplates()
diff --git a/unotest/source/cpp/macros_test.cxx b/unotest/source/cpp/macros_test.cxx
index ffc2b970393c..758dcc707347 100644
--- a/unotest/source/cpp/macros_test.cxx
+++ b/unotest/source/cpp/macros_test.cxx
@@ -14,6 +14,7 @@
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/document/MacroExecMode.hpp>
+#include <basic/basrdll.hxx>
#include <cppunit/TestAssert.h>
#include <rtl/ustrbuf.hxx>
#include <comphelper/sequence.hxx>
@@ -22,6 +23,13 @@ using namespace css;
namespace unotest {
+MacrosTest::MacrosTest()
+ : mpDll(std::make_unique<BasicDLL>())
+{
+}
+
+MacrosTest::~MacrosTest() = default;
+
uno::Reference<css::lang::XComponent> MacrosTest::loadFromDesktop(const OUString& rURL, const OUString& rDocService, const uno::Sequence<beans::PropertyValue>& rExtraArgs)
{
CPPUNIT_ASSERT_MESSAGE("no desktop", mxDesktop.is());