Don't allow stack addresses to escape via long-life handlers.

This commit is contained in:
Jeff Young 2025-09-02 14:19:17 +01:00
parent 6a171e11fb
commit cff261ce2e
6 changed files with 38 additions and 24 deletions

View File

@ -506,8 +506,10 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
picker->ClearHandlers();
picker->SetClickHandler(
[this, simFrame]( const VECTOR2D& aPosition )
[this]( const VECTOR2D& aPosition )
{
KIWAY_PLAYER* player = m_frame->Kiway().Player( FRAME_SIMULATOR, false );
SIMULATOR_FRAME* simFrame = static_cast<SIMULATOR_FRAME*>( player );
SCH_SELECTION_TOOL* selTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
// We do not really want to keep an item selected in schematic,
@ -555,7 +557,9 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
}
else if( currentNames.size() == 1 )
{
simFrame->AddCurrentTrace( currentNames.at( 0 ) );
if( simFrame )
simFrame->AddCurrentTrace( currentNames.at( 0 ) );
return true;
}
@ -564,7 +568,9 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
if( modelPinIndex != SIM_MODEL_PIN::NOT_CONNECTED )
{
wxString name = currentNames.at( modelPinIndex );
simFrame->AddCurrentTrace( name );
if( simFrame )
simFrame->AddCurrentTrace( name );
}
}
catch( const IO_ERROR& e )
@ -579,7 +585,8 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
wxString spiceNet = UnescapeString( conn->Name() );
NETLIST_EXPORTER_SPICE::ConvertToSpiceMarkup( &spiceNet );
simFrame->AddVoltageTrace( wxString::Format( "V(%s)", spiceNet ) );
if( simFrame )
simFrame->AddVoltageTrace( wxString::Format( "V(%s)", spiceNet ) );
}
}
@ -587,7 +594,7 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
} );
picker->SetMotionHandler(
[this, picker]( const VECTOR2D& aPos )
[this]( const VECTOR2D& aPos )
{
SCH_COLLECTOR collector;
collector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
@ -610,9 +617,9 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
}
if( item && item->Type() == SCH_PIN_T )
picker->SetCursor( KICURSOR::CURRENT_PROBE );
m_toolMgr->GetTool<PICKER_TOOL>()->SetCursor( KICURSOR::CURRENT_PROBE );
else
picker->SetCursor( KICURSOR::VOLTAGE_PROBE );
m_toolMgr->GetTool<PICKER_TOOL>()->SetCursor( KICURSOR::VOLTAGE_PROBE );
if( m_pickerItem != item )
{

View File

@ -119,6 +119,7 @@ int SCH_GROUP_TOOL::PickNewMember( const TOOL_EVENT& aEvent )
break;
}
picker->ClearHandlers();
m_frame->GetCanvas()->SetStatusPopup( nullptr );
return 0;

View File

@ -1948,7 +1948,6 @@ int BOARD_INSPECTION_TOOL::ClearHighlight( const TOOL_EVENT& aEvent )
int BOARD_INSPECTION_TOOL::LocalRatsnestTool( const TOOL_EVENT& aEvent )
{
PCB_PICKER_TOOL* picker = m_toolMgr->GetTool<PCB_PICKER_TOOL>();
BOARD* board = getModel<BOARD>();
// Deactivate other tools; particularly important if another PICKER is currently running
Activate();
@ -1958,7 +1957,7 @@ int BOARD_INSPECTION_TOOL::LocalRatsnestTool( const TOOL_EVENT& aEvent )
picker->ClearHandlers();
picker->SetClickHandler(
[this, board]( const VECTOR2D& pt ) -> bool
[this]( const VECTOR2D& pt ) -> bool
{
PCB_SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
@ -1978,7 +1977,7 @@ int BOARD_INSPECTION_TOOL::LocalRatsnestTool( const TOOL_EVENT& aEvent )
if( selection.Empty() )
{
// Clear the previous local ratsnest if we click off all items
for( FOOTPRINT* fp : board->Footprints() )
for( FOOTPRINT* fp : getModel<BOARD>()->Footprints() )
{
for( PAD* pad : fp->Pads() )
pad->SetLocalRatsnestVisible( displayOptions().m_ShowGlobalRatsnest );
@ -2011,11 +2010,11 @@ int BOARD_INSPECTION_TOOL::LocalRatsnestTool( const TOOL_EVENT& aEvent )
} );
picker->SetFinalizeHandler(
[this, board]( int aCondition )
[this]( int aCondition )
{
if( aCondition != PCB_PICKER_TOOL::END_ACTIVATE )
{
for( FOOTPRINT* fp : board->Footprints() )
for( FOOTPRINT* fp : getModel<BOARD>()->Footprints() )
{
for( PAD* pad : fp->Pads() )
pad->SetLocalRatsnestVisible( displayOptions().m_ShowGlobalRatsnest );

View File

@ -3317,6 +3317,8 @@ bool EDIT_TOOL::pickReferencePoint( const wxString& aTooltip, const wxString& aS
}
}
picker->ClearHandlers();
// Ensure statusPopup is hidden after use and before deleting it:
canvas()->SetStatusPopup( nullptr );
m_statusPopup->Hide();

View File

@ -129,6 +129,7 @@ int PCB_GROUP_TOOL::PickNewMember( const TOOL_EVENT& aEvent )
break;
}
picker->ClearHandlers();
m_frame->GetCanvas()->SetStatusPopup( nullptr );
return 0;

View File

@ -260,11 +260,12 @@ int PCB_PICKER_TOOL::SelectPointInteractively( const TOOL_EVENT& aEvent )
statusPopup.SetText( wxGetTranslation( params.m_Prompt ) );
const auto sendPoint = [&]( const std::optional<VECTOR2I>& aPoint )
{
statusPopup.Hide();
params.m_Receiver->UpdatePickedPoint( aPoint );
};
const auto sendPoint =
[&]( const std::optional<VECTOR2I>& aPoint )
{
statusPopup.Hide();
params.m_Receiver->UpdatePickedPoint( aPoint );
};
SetSnapping( true );
SetCursor( KICURSOR::PLACE );
@ -306,11 +307,13 @@ int PCB_PICKER_TOOL::SelectPointInteractively( const TOOL_EVENT& aEvent )
// Drop into the main event loop
Main( aEvent );
ClearHandlers();
canvas()->SetStatusPopup( nullptr );
frame()->PopTool( aEvent );
return 0;
}
int PCB_PICKER_TOOL::SelectItemInteractively( const TOOL_EVENT& aEvent )
{
INTERACTIVE_PARAMS params = aEvent.Parameter<INTERACTIVE_PARAMS>();
@ -325,11 +328,12 @@ int PCB_PICKER_TOOL::SelectItemInteractively( const TOOL_EVENT& aEvent )
statusPopup.SetText( wxGetTranslation( params.m_Prompt ) );
const auto sendItem = [&]( const EDA_ITEM* aItem )
{
statusPopup.Hide();
params.m_Receiver->UpdatePickedItem( aItem );
};
const auto sendItem =
[&]( const EDA_ITEM* aItem )
{
statusPopup.Hide();
params.m_Receiver->UpdatePickedItem( aItem );
};
SetCursor( KICURSOR::BULLSEYE );
SetSnapping( false );
@ -340,8 +344,7 @@ int PCB_PICKER_TOOL::SelectItemInteractively( const TOOL_EVENT& aEvent )
{
m_toolMgr->RunAction( ACTIONS::selectionClear );
const PCB_SELECTION& sel = selectionTool->RequestSelection(
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector,
PCB_SELECTION_TOOL* sTool )
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
{
} );
@ -383,6 +386,7 @@ int PCB_PICKER_TOOL::SelectItemInteractively( const TOOL_EVENT& aEvent )
// Drop into the main event loop
Main( aEvent );
ClearHandlers();
canvas()->SetStatusPopup( nullptr );
frame()->PopTool( aEvent );
return 0;