From 3fea2df08c0ca37f27add2ea51d12d47154f2e9a Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Tue, 4 Jun 2019 13:18:20 -0700 Subject: [PATCH] pcbnew: ClearPcb() without queuing tools When exiting pcbnew, we only want to run the sections of ClearPcb that remove the old pcb data. We do not want to queue events that handle initializing a new pcb. These were caught after freeing memory in some cases, leading to segfaults. Fixes: lp:1831560 * https://bugs.launchpad.net/kicad/+bug/1831560 --- pcbnew/initpcb.cpp | 45 +++++++++++++++++++++------------------ pcbnew/pcb_edit_frame.cpp | 2 +- pcbnew/pcb_edit_frame.h | 3 ++- 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/pcbnew/initpcb.cpp b/pcbnew/initpcb.cpp index 799bf92e0..03ad1a895 100644 --- a/pcbnew/initpcb.cpp +++ b/pcbnew/initpcb.cpp @@ -36,7 +36,7 @@ #include -bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery ) +bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery, bool aFinal ) { if( GetBoard() == NULL ) return false; @@ -60,33 +60,36 @@ bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery ) bool showGrid = IsElementVisible( LAYER_GRID ); bool showRats = IsElementVisible( LAYER_RATSNEST ); - // delete the old BOARD and create a new BOARD so that the default - // layer names are put into the BOARD. - SetBoard( new BOARD() ); - SetElementVisibility( LAYER_GRID, showGrid ); - SetElementVisibility( LAYER_RATSNEST, showRats ); + if( !aFinal ) + { + // delete the old BOARD and create a new BOARD so that the default + // layer names are put into the BOARD. + SetBoard( new BOARD() ); + SetElementVisibility( LAYER_GRID, showGrid ); + SetElementVisibility( LAYER_RATSNEST, showRats ); - // clear filename, to avoid overwriting an old file - GetBoard()->SetFileName( wxEmptyString ); + // clear filename, to avoid overwriting an old file + GetBoard()->SetFileName( wxEmptyString ); - GetScreen()->InitDataPoints( GetPageSizeIU() ); + GetScreen()->InitDataPoints( GetPageSizeIU() ); - GetBoard()->ResetHighLight(); + GetBoard()->ResetHighLight(); - // Enable all layers (SetCopperLayerCount() will adjust the copper layers enabled) - GetBoard()->SetEnabledLayers( LSET().set() ); + // Enable all layers (SetCopperLayerCount() will adjust the copper layers enabled) + GetBoard()->SetEnabledLayers( LSET().set() ); - // Default copper layers count set to 2: double layer board - GetBoard()->SetCopperLayerCount( 2 ); + // Default copper layers count set to 2: double layer board + GetBoard()->SetCopperLayerCount( 2 ); - // Update display (some options depend on the board setup) - GetBoard()->SetVisibleLayers( LSET().set() ); - ReCreateLayerBox(); - ReCreateAuxiliaryToolbar(); - ReFillLayerWidget(); - UpdateTitle(); + // Update display (some options depend on the board setup) + GetBoard()->SetVisibleLayers( LSET().set() ); + ReCreateLayerBox(); + ReCreateAuxiliaryToolbar(); + ReFillLayerWidget(); + UpdateTitle(); - Zoom_Automatique( false ); + Zoom_Automatique( false ); + } return true; } diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index 406a20519..df894dfdc 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -548,7 +548,7 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event ) // Delete board structs and undo/redo lists, to avoid crash on exit // when deleting some structs (mainly in undo/redo lists) too late - Clear_Pcb( false ); + Clear_Pcb( false, true ); // do not show the window because ScreenPcb will be deleted and we do not // want any paint event diff --git a/pcbnew/pcb_edit_frame.h b/pcbnew/pcb_edit_frame.h index 8d7a016e6..78d7902d9 100644 --- a/pcbnew/pcb_edit_frame.h +++ b/pcbnew/pcb_edit_frame.h @@ -681,8 +681,9 @@ public: * Function Clear_Pcb * delete all and reinitialize the current board * @param aQuery = true to prompt user for confirmation, false to initialize silently + * @param aFinal = if true, we are clearing the board to exit, so don't run more events */ - bool Clear_Pcb( bool aQuery ); + bool Clear_Pcb( bool aQuery, bool aFinal = false ); ///> @copydoc PCB_BASE_FRAME::SetBoard() void SetBoard( BOARD* aBoard ) override; -- 2.20.1