Schematic editor: fix some issues that can crash the editor on closing.

- Add a test to be sure a SCHEMATIC exists before trying to use it
- Delete items in Repeat list and undo/redo list before deleting the schematic
- Delete also these items when loading a new schematic (the repeat list was
not cleaned previously)
Before these fixes I see a use after delete issue due to dangling pointers
stored in Repeat list.
This commit is contained in:
jean-pierre charras 2024-06-14 16:57:57 +02:00
parent 7fef6e8d83
commit d778cb6647
6 changed files with 32 additions and 0 deletions

View File

@ -147,6 +147,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
// unload current project file before loading new // unload current project file before loading new
{ {
ClearUndoRedoList(); ClearUndoRedoList();
ClearRepeatItemsList();
SetScreen( nullptr ); SetScreen( nullptr );
m_toolManager->GetTool<EE_INSPECTION_TOOL>()->Reset( TOOL_BASE::SUPERMODEL_RELOAD ); m_toolManager->GetTool<EE_INSPECTION_TOOL>()->Reset( TOOL_BASE::SUPERMODEL_RELOAD );
CreateScreens(); CreateScreens();
@ -748,6 +749,7 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
// Don't leave dangling pointers to previously-opened document. // Don't leave dangling pointers to previously-opened document.
m_toolManager->GetTool<EE_SELECTION_TOOL>()->ClearSelection(); m_toolManager->GetTool<EE_SELECTION_TOOL>()->ClearSelection();
ClearUndoRedoList(); ClearUndoRedoList();
ClearRepeatItemsList();
if( setProject ) if( setProject )
{ {
@ -1472,6 +1474,7 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType,
} }
ClearUndoRedoList(); ClearUndoRedoList();
ClearRepeatItemsList();
initScreenZoom(); initScreenZoom();
SetSheetNumberAndCount(); SetSheetNumberAndCount();

View File

@ -442,6 +442,11 @@ SCH_EDIT_FRAME::~SCH_EDIT_FRAME()
if( m_schematic ) if( m_schematic )
m_schematic->RemoveAllListeners(); m_schematic->RemoveAllListeners();
// Delete all items not in draw list before deleting schematic
// to avoid dangling pointers stored in these items
ClearUndoRedoList();
ClearRepeatItemsList();
delete m_schematic; delete m_schematic;
m_schematic = nullptr; m_schematic = nullptr;

View File

@ -715,6 +715,15 @@ public:
return m_items_to_repeat; return m_items_to_repeat;
} }
/**
* Clear the list of items which are to be repeated with the insert key.
* These objects are owned by this container.
*/
void ClearRepeatItemsList()
{
m_items_to_repeat.clear();
}
EDA_ITEM* GetItem( const KIID& aId ) const override; EDA_ITEM* GetItem( const KIID& aId ) const override;
/** /**

View File

@ -144,6 +144,11 @@ SCH_ITEM* SCH_ITEM::Duplicate( bool doClone ) const
SCHEMATIC* SCH_ITEM::Schematic() const SCHEMATIC* SCH_ITEM::Schematic() const
{ {
if( !SCHEMATIC::m_IsSchematicExists )
{
return nullptr;
}
EDA_ITEM* parent = GetParent(); EDA_ITEM* parent = GetParent();
while( parent ) while( parent )

View File

@ -37,6 +37,8 @@
#include <sim/spice_value.h> #include <sim/spice_value.h>
#include <netlist_exporter_spice.h> #include <netlist_exporter_spice.h>
bool SCHEMATIC::m_IsSchematicExists = false;
SCHEMATIC::SCHEMATIC( PROJECT* aPrj ) : SCHEMATIC::SCHEMATIC( PROJECT* aPrj ) :
EDA_ITEM( nullptr, SCHEMATIC_T ), EDA_ITEM( nullptr, SCHEMATIC_T ),
m_project( nullptr ), m_project( nullptr ),
@ -44,6 +46,7 @@ SCHEMATIC::SCHEMATIC( PROJECT* aPrj ) :
{ {
m_currentSheet = new SCH_SHEET_PATH(); m_currentSheet = new SCH_SHEET_PATH();
m_connectionGraph = new CONNECTION_GRAPH( this ); m_connectionGraph = new CONNECTION_GRAPH( this );
m_IsSchematicExists = true;
SetProject( aPrj ); SetProject( aPrj );
@ -124,6 +127,8 @@ SCHEMATIC::~SCHEMATIC()
delete m_currentSheet; delete m_currentSheet;
delete m_connectionGraph; delete m_connectionGraph;
m_IsSchematicExists = false;
} }

View File

@ -305,6 +305,11 @@ public:
*/ */
void RemoveAllListeners(); void RemoveAllListeners();
/**
* True if a SCHEMATIC exists, false if not
*/
static bool m_IsSchematicExists;
#if defined(DEBUG) #if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ) const override {} void Show( int nestLevel, std::ostream& os ) const override {}
#endif #endif