From ff52353d7674079f2f39e95d47d55887c178484c Mon Sep 17 00:00:00 2001 From: vsr Date: Fri, 9 Oct 2009 11:25:18 +0000 Subject: [PATCH] Issue 0020527: EDF 1132 GUI: SIGSEGV at destruction of a Python module with GUI --- src/CAM/CAM_Application.cxx | 9 +- src/CAM/CAM_Application.h | 1 + .../SALOME_PYQT_GUI/SALOME_PYQT_Module.cxx | 4 +- .../SALOME_PYQT_ModuleLight.cxx | 82 ++++++++++--------- .../SALOME_PYQT_ModuleLight.h | 2 +- 5 files changed, 54 insertions(+), 44 deletions(-) diff --git a/src/CAM/CAM_Application.cxx b/src/CAM/CAM_Application.cxx index 61aa42d96..dab5b8143 100755 --- a/src/CAM/CAM_Application.cxx +++ b/src/CAM/CAM_Application.cxx @@ -88,8 +88,6 @@ CAM_Application::CAM_Application( const bool autoLoad ) */ CAM_Application::~CAM_Application() { - for ( QList::const_iterator it = myModules.begin(); it != myModules.end(); ++it ) - delete *it; } /*! @@ -437,6 +435,13 @@ void CAM_Application::beforeCloseDoc( SUIT_Study* theDoc ) (*it)->studyClosed( theDoc ); } +void CAM_Application::afterCloseDoc() +{ + for ( QList::const_iterator it = myModules.begin(); it != myModules.end(); ++it ) + delete *it; + myModules.clear(); +} + /*! \brief Set active study. \param study study to be made active diff --git a/src/CAM/CAM_Application.h b/src/CAM/CAM_Application.h index 5ce540555..e04876078 100755 --- a/src/CAM/CAM_Application.h +++ b/src/CAM/CAM_Application.h @@ -75,6 +75,7 @@ protected: virtual void moduleAdded( CAM_Module* ); virtual void beforeCloseDoc( SUIT_Study* ); + virtual void afterCloseDoc(); virtual bool activateModule( CAM_Module* = 0 ); virtual void setActiveStudy( SUIT_Study* ); diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.cxx b/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.cxx index 80da8eb31..42e24296b 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.cxx +++ b/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.cxx @@ -157,8 +157,8 @@ void SALOME_PYQT_Module::getEngineIOR() if ( !myInterp || !myModule ) return; - if ( PyObject_HasAttrString( myModule , "engineIOR" ) ) { - PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"engineIOR", (char*)"" ) ); + if ( PyObject_HasAttrString( myModule->get() , "engineIOR" ) ) { + PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"engineIOR", (char*)"" ) ); if ( !res ) { PyErr_Print(); } diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.cxx b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.cxx index 986b9e4e3..735f705f4 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.cxx +++ b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.cxx @@ -283,6 +283,10 @@ SALOME_PYQT_ModuleLight::~SALOME_PYQT_ModuleLight() { if ( myXmlHandler ) delete myXmlHandler; + if ( myInterp ) { + PyLockWrapper aLock = myInterp->GetLockWrapper(); + delete myModule; + } } /*! @@ -862,8 +866,8 @@ void SALOME_PYQT_ModuleLight::init( CAM_Application* app ) PyLockWrapper aLock = myInterp->GetLockWrapper(); // ... (the Python module is already imported) // ... finally call Python module's initialize() method - if ( PyObject_HasAttrString( myModule , "initialize" ) ) { - PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"initialize", (char*)"" ) ); + if ( PyObject_HasAttrString( myModule->get(), "initialize" ) ) { + PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"initialize", (char*)"" ) ); if ( !res ) { PyErr_Print(); } @@ -876,8 +880,8 @@ void SALOME_PYQT_ModuleLight::init( CAM_Application* app ) myWindowsMap.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea ); myWindowsMap.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea ); - if ( PyObject_HasAttrString( myModule , "windows" ) ) { - PyObjWrapper res1( PyObject_CallMethod( myModule, (char*)"windows", (char*)"" ) ); + if ( PyObject_HasAttrString( myModule->get() , "windows" ) ) { + PyObjWrapper res1( PyObject_CallMethod( myModule->get(), (char*)"windows", (char*)"" ) ); if ( !res1 ) { PyErr_Print(); } @@ -903,8 +907,8 @@ void SALOME_PYQT_ModuleLight::init( CAM_Application* app ) // get compatible view windows types from the Python module // by calling views() method - if ( PyObject_HasAttrString( myModule , "views" ) ) { - PyObjWrapper res2( PyObject_CallMethod( myModule, (char*)"views", (char*)"" ) ); + if ( PyObject_HasAttrString( myModule->get() , "views" ) ) { + PyObjWrapper res2( PyObject_CallMethod( myModule->get(), (char*)"views", (char*)"" ) ); if ( !res2 ) { PyErr_Print(); } @@ -962,8 +966,8 @@ void SALOME_PYQT_ModuleLight::activate( SUIT_Study* theStudy ) PyLockWrapper aLock = myInterp->GetLockWrapper(); // call Python module's activate() method (for the new modules) - if ( PyObject_HasAttrString( myModule , "activate" ) ) { - PyObject* res1 = PyObject_CallMethod( myModule, (char*)"activate", (char*)"" ); + if ( PyObject_HasAttrString( myModule->get() , "activate" ) ) { + PyObject* res1 = PyObject_CallMethod( myModule->get(), (char*)"activate", (char*)"" ); if ( !res1 || !PyBool_Check( res1 ) ) { PyErr_Print(); // always true for old modules (no return value) @@ -1035,8 +1039,8 @@ void SALOME_PYQT_ModuleLight::customize( SUIT_Study* theStudy ) if ( IsCallOldMethods ) { // call Python module's setSettings() method (obsolete) - if ( PyObject_HasAttrString( myModule , "setSettings" ) ) { - PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"setSettings", (char*)"" ) ); + if ( PyObject_HasAttrString( myModule->get() , "setSettings" ) ) { + PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"setSettings", (char*)"" ) ); if( !res ) { PyErr_Print(); } @@ -1062,8 +1066,8 @@ void SALOME_PYQT_ModuleLight::deactivate( SUIT_Study* theStudy ) return; } // then call Python module's deactivate() method - if ( PyObject_HasAttrString( myModule , "deactivate" ) ) { - PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"deactivate", (char*)"" ) ); + if ( PyObject_HasAttrString( myModule->get() , "deactivate" ) ) { + PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"deactivate", (char*)"" ) ); if( !res ) { PyErr_Print(); } @@ -1116,8 +1120,8 @@ void SALOME_PYQT_ModuleLight::studyChanged( SUIT_Study* theStudy ) PyLockWrapper aLock = myInterp->GetLockWrapper(); // call Python module's activeStudyChanged() method - if ( PyObject_HasAttrString( myModule , "activeStudyChanged" ) ) { - PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"activeStudyChanged", (char*)"i", aStudyId ) ); + if ( PyObject_HasAttrString( myModule->get(), "activeStudyChanged" ) ) { + PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"activeStudyChanged", (char*)"i", aStudyId ) ); if( !res ) { PyErr_Print(); } @@ -1150,10 +1154,10 @@ void SALOME_PYQT_ModuleLight::contextMenu( const QString& theContext, QMenu* the QString aContext( "" ), aObject( "" ), aParent( theContext ); - if ( IsCallOldMethods && PyObject_HasAttrString( myModule , "definePopup" ) ) { + if ( IsCallOldMethods && PyObject_HasAttrString( myModule->get(), "definePopup" ) ) { // call definePopup() Python module's function // this is obsolete function, used only for compatibility reasons - PyObjWrapper res( PyObject_CallMethod( myModule, + PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"definePopup", (char*)"sss", theContext.toLatin1().constData(), @@ -1181,8 +1185,8 @@ void SALOME_PYQT_ModuleLight::contextMenu( const QString& theContext, QMenu* the PyObjWrapper sipPopup( sipBuildResult( 0, "M", thePopupMenu, sipClass_QMenu ) ); // then call Python module's createPopupMenu() method (for new modules) - if ( PyObject_HasAttrString( myModule , "createPopupMenu" ) ) { - PyObjWrapper res1( PyObject_CallMethod( myModule, + if ( PyObject_HasAttrString( myModule->get(), "createPopupMenu" ) ) { + PyObjWrapper res1( PyObject_CallMethod( myModule->get(), (char*)"createPopupMenu", (char*)"Os", sipPopup.get(), @@ -1192,10 +1196,10 @@ void SALOME_PYQT_ModuleLight::contextMenu( const QString& theContext, QMenu* the } } - if ( IsCallOldMethods && PyObject_HasAttrString( myModule , "customPopup" ) ) { + if ( IsCallOldMethods && PyObject_HasAttrString( myModule->get(), "customPopup" ) ) { // call customPopup() Python module's function // this is obsolete function, used only for compatibility reasons - PyObjWrapper res2( PyObject_CallMethod( myModule, + PyObjWrapper res2( PyObject_CallMethod( myModule->get(), (char*)"customPopup", (char*)"Osss", sipPopup.get(), @@ -1225,8 +1229,8 @@ void SALOME_PYQT_ModuleLight::guiEvent( const int theId ) if ( !myInterp || !myModule ) return; - if ( PyObject_HasAttrString( myModule , "OnGUIEvent" ) ) { - PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"OnGUIEvent", (char*)"i", theId ) ); + if ( PyObject_HasAttrString( myModule->get(), "OnGUIEvent" ) ) { + PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"OnGUIEvent", (char*)"i", theId ) ); if( !res ) { PyErr_Print(); } @@ -1252,8 +1256,8 @@ void SALOME_PYQT_ModuleLight::initPreferences() // might be called during the module intialization process myInitModule = this; - if ( PyObject_HasAttrString( myModule , "createPreferences" ) ) { - PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"createPreferences", (char*)"" ) ); + if ( PyObject_HasAttrString( myModule->get(), "createPreferences" ) ) { + PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"createPreferences", (char*)"" ) ); if( !res ) { PyErr_Print(); } @@ -1335,7 +1339,7 @@ void SALOME_PYQT_ModuleLight::importModule() PyLockWrapper aLock = myInterp->GetLockWrapper(); // ... then import a module QString aMod = name() + "GUI"; - myModule = PyImport_ImportModule( aMod.toLatin1().data() ); + myModule = new PyObjWrapper( PyImport_ImportModule( aMod.toLatin1().data() ) ); if( !myModule ) { // Error! PyErr_Print(); @@ -1388,8 +1392,8 @@ void SALOME_PYQT_ModuleLight::setWorkSpace() } PyObjWrapper pyws( sipBuildResult( 0, "M", aWorkspace, sipClass_QWidget ) ); // ... and finally call Python module's setWorkspace() method (obsolete) - if ( PyObject_HasAttrString( myModule , "setWorkSpace" ) ) { - PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"setWorkSpace", (char*)"O", pyws.get() ) ); + if ( PyObject_HasAttrString( myModule->get(), "setWorkSpace" ) ) { + PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"setWorkSpace", (char*)"O", pyws.get() ) ); if( !res ) { PyErr_Print(); } @@ -1415,8 +1419,8 @@ void SALOME_PYQT_ModuleLight::prefChanged( const QString& section, const QString if ( !myInterp || !myModule ) return; - if ( PyObject_HasAttrString( myModule , "preferenceChanged" ) ) { - PyObjWrapper res( PyObject_CallMethod( myModule, + if ( PyObject_HasAttrString( myModule->get(), "preferenceChanged" ) ) { + PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"preferenceChanged", (char*)"ss", section.toLatin1().constData(), @@ -1813,12 +1817,12 @@ void SALOME_PYQT_ModuleLight::activeViewChanged( const SUIT_ViewWindow* pview ) connectView( pview ); - if ( PyObject_HasAttrString( myModule, "activeViewChanged" ) ) + if ( PyObject_HasAttrString( myModule->get(), "activeViewChanged" ) ) { if ( !pview ) return; - PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"activeViewChanged", (char*)"i" , pview->getId() ) ); + PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"activeViewChanged", (char*)"i" , pview->getId() ) ); if( !res ) PyErr_Print(); } @@ -1860,9 +1864,9 @@ void SALOME_PYQT_ModuleLight::viewCloned( const SUIT_ViewWindow* pview ) if ( !myInterp || !myModule || !pview ) return; - if ( PyObject_HasAttrString( myModule, "viewCloned" ) ) + if ( PyObject_HasAttrString( myModule->get(), "viewCloned" ) ) { - PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"viewCloned", (char*)"i", pview->getId() ) ); + PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"viewCloned", (char*)"i", pview->getId() ) ); if( !res ) PyErr_Print(); } @@ -1904,9 +1908,9 @@ void SALOME_PYQT_ModuleLight::viewClosed( const SUIT_ViewWindow* pview ) if ( !myInterp || !myModule ) return; - if ( PyObject_HasAttrString( myModule, "viewClosed" ) ) + if ( PyObject_HasAttrString( myModule->get(), "viewClosed" ) ) { - PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"viewClosed", (char*)"i", pview->getId() ) ); + PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"viewClosed", (char*)"i", pview->getId() ) ); if ( !res ) { PyErr_Print(); @@ -2372,8 +2376,8 @@ void SALOME_PYQT_ModuleLight::saveEvent(QStringList& theListOfFiles) if ( !myInterp || !myModule || (it == theListOfFiles.end())) return; - if ( PyObject_HasAttrString(myModule , "saveFiles") ) { - PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"saveFiles", + if ( PyObject_HasAttrString(myModule->get(), "saveFiles") ) { + PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"saveFiles", (char*)"s", (*it).toLatin1().constData())); if( !res ) { PyErr_Print(); @@ -2451,8 +2455,8 @@ void SALOME_PYQT_ModuleLight::openEvent(QStringList theListOfFiles, bool &opened PyObjWrapper sipList( sipBuildResult( 0, "M", theList, sipClass_QStringList ) ); - if ( PyObject_HasAttrString(myModule , "openFiles") ) { - PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"openFiles", + if ( PyObject_HasAttrString(myModule->get() , "openFiles") ) { + PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"openFiles", (char*)"O", sipList.get())); if( !res || !PyBool_Check( res )) { PyErr_Print(); diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.h b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.h index 972788f69..f9066c640 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.h +++ b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.h @@ -63,7 +63,7 @@ private: bool myLastActivateStatus; //!< latest module activation status protected: - PyObjWrapper myModule; //!< Python GUI module + PyObjWrapper* myModule; //!< Python GUI module PyInterp_Interp* myInterp; //!< current Python subinterpreter static InterpMap myInterpMap; //!< study to Python subinterpreter map -- 2.39.2