From 3ecb9b4bd7dc70664bbb8d7c957ea8dc5015223f Mon Sep 17 00:00:00 2001 From: Bjoern Michaelsen Date: Wed, 29 Mar 2017 00:01:04 +0200 Subject: tdf#99352: assert on stray VclPtrs past DeInit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ignore on Windows for now, as it is acting up Change-Id: I98dbb887ed556b58188870c3eb3de1327bc58109 Reviewed-on: https://gerrit.libreoffice.org/35816 Tested-by: Jenkins Reviewed-by: Björn Michaelsen --- include/vcl/vclmain.hxx | 8 +++++- include/vcl/vclptr.hxx | 15 +++++++++++ svtools/source/dialogs/addresstemplate.cxx | 25 +++++++++--------- vcl/inc/svdata.hxx | 4 +++ vcl/source/app/svdata.cxx | 30 ++++++++++++--------- vcl/source/app/svmain.cxx | 42 ++++++++++++++++++++++++++++++ 6 files changed, 98 insertions(+), 26 deletions(-) diff --git a/include/vcl/vclmain.hxx b/include/vcl/vclmain.hxx index f58b259a761c..54a630c43223 100644 --- a/include/vcl/vclmain.hxx +++ b/include/vcl/vclmain.hxx @@ -12,6 +12,10 @@ #include +#ifdef DBG_UTIL +#include +#endif + namespace vclmain { // Function called from vclmain's implementation of main, needs to be @@ -19,7 +23,9 @@ namespace vclmain { // instance of Application (where the Application constructor takes care to link // that instance to ImplSVData.mpApp): void createApplication(); - +#ifdef DBG_UTIL +VCL_DLLPUBLIC bool isAlive(); +#endif } #endif diff --git a/include/vcl/vclptr.hxx b/include/vcl/vclptr.hxx index 12cbb28b3ab5..906cd788c2af 100644 --- a/include/vcl/vclptr.hxx +++ b/include/vcl/vclptr.hxx @@ -29,6 +29,12 @@ #include #include +#ifdef DBG_UTIL +#ifndef WNT +#include +#endif +#endif + /// @cond INTERNAL namespace vcl { namespace detail { @@ -136,6 +142,15 @@ public: { } +#ifdef DBG_UTIL +#ifndef WNT + virtual ~VclPtr() + { + assert(m_rInnerRef.get() == nullptr || vclmain::isAlive()); + } +#endif +#endif + /** * A construction helper for VclPtr. Since VclPtr types are created * with a reference-count of one - to help fit into the existing diff --git a/svtools/source/dialogs/addresstemplate.cxx b/svtools/source/dialogs/addresstemplate.cxx index b07207d88332..91de032185f1 100644 --- a/svtools/source/dialogs/addresstemplate.cxx +++ b/svtools/source/dialogs/addresstemplate.cxx @@ -49,6 +49,7 @@ #include #include #include +#include namespace svt @@ -423,8 +424,8 @@ void AssignmentPersistentData::ImplCommit() struct AddressBookSourceDialogData { - VclPtr pFieldLabels[FIELD_PAIRS_VISIBLE * 2]; - VclPtr pFields[FIELD_PAIRS_VISIBLE * 2]; + std::array, FIELD_PAIRS_VISIBLE*2> pFieldLabels; + std::array, FIELD_PAIRS_VISIBLE*2> pFields; /// when working transient, we need the data source Reference< XDataSource > @@ -449,27 +450,27 @@ void AssignmentPersistentData::ImplCommit() AddressBookSourceDialogData( ) - :nFieldScrollPos(0) + :pFieldLabels{{nullptr}} + ,pFields{{nullptr}} + ,nFieldScrollPos(0) ,nLastVisibleListIndex(0) ,bOddFieldNumber(false) ,bWorkingPersistent( true ) ,pConfigData( new AssignmentPersistentData ) { - memset(pFieldLabels, 0, sizeof(pFieldLabels)); - memset(pFields, 0, sizeof(pFields)); } AddressBookSourceDialogData( const Reference< XDataSource >& _rxTransientDS, const OUString& _rDataSourceName, const OUString& _rTableName, const Sequence< AliasProgrammaticPair >& _rFields ) - :m_xTransientDataSource( _rxTransientDS ) + :pFieldLabels{{nullptr}} + ,pFields{{nullptr}} + ,m_xTransientDataSource( _rxTransientDS ) ,nFieldScrollPos(0) ,nLastVisibleListIndex(0) ,bOddFieldNumber(false) ,bWorkingPersistent( false ) ,pConfigData( new AssigmentTransientData( _rDataSourceName, _rTableName, _rFields ) ) { - memset(pFieldLabels, 0, sizeof(pFieldLabels)); - memset(pFields, 0, sizeof(pFields)); } // Copy assignment is forbidden and not implemented. @@ -977,14 +978,14 @@ void AssignmentPersistentData::ImplCommit() // loop through our field control rows and do some adjustments // for the new texts - VclPtr* pLeftLabelControl = m_pImpl->pFieldLabels; - VclPtr* pRightLabelControl = pLeftLabelControl + 1; + auto pLeftLabelControl = m_pImpl->pFieldLabels.begin(); + auto pRightLabelControl = pLeftLabelControl+1; auto pLeftColumnLabel = m_pImpl->aFieldLabels.cbegin() + 2 * _nPos; auto pRightColumnLabel = pLeftColumnLabel + 1; // for the focus movement and the selection scroll - VclPtr* pLeftListControl = m_pImpl->pFields; - VclPtr* pRightListControl = pLeftListControl + 1; + auto pLeftListControl = m_pImpl->pFields.begin(); + auto pRightListControl = pLeftListControl + 1; // for the focus movement sal_Int32 nOldFocusRow = -1; diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx index f14ee66eeeba..b3c7f466a3bc 100644 --- a/vcl/inc/svdata.hxx +++ b/vcl/inc/svdata.hxx @@ -102,6 +102,7 @@ typedef std::pair, ImplPostEventData *> ImplPostEventPair; struct ImplSVAppData { + ~ImplSVAppData(); enum ImeStatusWindowMode { ImeStatusWindowMode_UNKNOWN, @@ -182,6 +183,7 @@ struct ImplSVGDIData struct ImplSVWinData { + ~ImplSVWinData(); VclPtr mpFirstFrame; // First FrameWindow VclPtr mpAppWin; // Application-Window VclPtr mpFocusWin; // window, that has the focus @@ -227,6 +229,7 @@ struct ImplSVCtrlData struct ImplSVHelpData { + ~ImplSVHelpData(); bool mbContextHelp = false; // is ContextHelp enabled bool mbExtHelp = false; // is ExtendedHelp enabled bool mbExtHelpMode = false; // is in ExtendedHelp Mode @@ -308,6 +311,7 @@ struct BlendFrameCache struct ImplSVData { + ~ImplSVData(); SalData* mpSalData = nullptr; SalInstance* mpDefInst = nullptr; // Default SalInstance Application* mpApp = nullptr; // pApp diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx index b27abd9aa41f..65742be51afa 100644 --- a/vcl/source/app/svdata.cxx +++ b/vcl/source/app/svdata.cxx @@ -28,14 +28,19 @@ #include #include -#include -#include -#include -#include -#include #include +#include #include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include #include #include "salinst.hxx" #include "salframe.hxx" @@ -79,14 +84,6 @@ SalSystem* ImplGetSalSystem() return pSVData->mpSalSystem; } -ImplSVGDIData::~ImplSVGDIData() -{ - // FIXME: deliberately leak any remaining OutputDevice - // until we have their pGraphics reference counted, doing - // any disposes so late in shutdown is rather unsafe. - memset( this, 0, sizeof( ImplSVGDIData ) ); -} - void ImplDeInitSVData() { ImplSVData* pSVData = ImplGetSVData(); @@ -301,4 +298,11 @@ void LocaleConfigurationListener::ConfigurationChanged( utl::ConfigurationBroadc AllSettings::LocaleSettingsChanged( nHint ); } + +ImplSVData::~ImplSVData() {} +ImplSVAppData::~ImplSVAppData() {} +ImplSVGDIData::~ImplSVGDIData() {} +ImplSVWinData::~ImplSVWinData() {} +ImplSVHelpData::~ImplSVHelpData() {} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx index c97080e46c1c..781f6b707ce1 100644 --- a/vcl/source/app/svmain.cxx +++ b/vcl/source/app/svmain.cxx @@ -46,6 +46,11 @@ #include #include #include +#include +#include +#include +#include +#include #ifdef _WIN32 #include @@ -267,6 +272,17 @@ static bool isInitVCL() pSVData->mpDefInst != nullptr; } +#ifdef DBG_UTIL +namespace vclmain +{ + bool isAlive() + { + return ImplGetSVData()->mpDefInst; + } +} +#endif + + bool InitVCL() { if( pExceptionHandler != nullptr ) @@ -364,6 +380,7 @@ void DeInitVCL() ::comphelper::JoinAsyncEventNotifiers(); } ImplSVData* pSVData = ImplGetSVData(); + // lp#1560328: clear cache before disposing rest of VCL if(pSVData->mpBlendFrameCache) pSVData->mpBlendFrameCache->m_aLastResult.Clear(); @@ -545,6 +562,31 @@ void DeInitVCL() delete pSVData->mpSalTimer; pSVData->mpSalTimer = nullptr; + pSVData->mpDefaultWin = nullptr; + pSVData->mpIntroWindow = nullptr; + pSVData->maAppData.mpActivePopupMenu = nullptr; + pSVData->maAppData.mpWheelWindow = nullptr; + pSVData->maGDIData.mpFirstWinGraphics = nullptr; + pSVData->maGDIData.mpLastWinGraphics = nullptr; + pSVData->maGDIData.mpFirstVirGraphics = nullptr; + pSVData->maGDIData.mpLastVirGraphics = nullptr; + pSVData->maGDIData.mpFirstPrnGraphics = nullptr; + pSVData->maGDIData.mpLastPrnGraphics = nullptr; + pSVData->maGDIData.mpFirstVirDev = nullptr; + pSVData->maGDIData.mpLastVirDev = nullptr; + pSVData->maGDIData.mpFirstPrinter = nullptr; + pSVData->maGDIData.mpLastPrinter = nullptr; + pSVData->maWinData.mpFirstFrame = nullptr; + pSVData->maWinData.mpAppWin = nullptr; + pSVData->maWinData.mpActiveApplicationFrame = nullptr; + pSVData->maWinData.mpCaptureWin = nullptr; + pSVData->maWinData.mpLastDeacWin = nullptr; + pSVData->maWinData.mpFirstFloat = nullptr; + pSVData->maWinData.mpLastExecuteDlg = nullptr; + pSVData->maWinData.mpExtTextInputWin = nullptr; + pSVData->maWinData.mpTrackWin = nullptr; + pSVData->maWinData.mpAutoScrollWin = nullptr; + pSVData->maWinData.mpLastWheelWindow = nullptr; // Deinit Sal if (pSVData->mpDefInst) { -- cgit