Hi Julius,
The TOOL_EVENT_UTILS functions are for generic event decision logic.
That PCB_ACTIONS::routerInlineDrag acts as to cancel an in progress
routing is specific to the ROUTER_TOOL event loop, so it should
probably be OR'ed in in ROUTER_TOOL::performRouting(), like this:
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt )
| | evt->IsAction( &PCB_ACTIONS::routerInlineDrag )
| | evt->IsUndoRedo() )
As you can see UndoRedo also has a special handling in the router tool
that is not shared with all other tools by inclusion in
IsCancelInteractive.
Cheers,
John
On Tue, Feb 28, 2017 at 9:10 AM, Julius Schmidt <aiju@xxxxxxxxxx> wrote:
> The attached patch fixes a bug where triggering InlineDrag while routing
> is in progress will crash pcbnew. The problem is that the InlineDrag
> event does not terminate performRouting. Once InlineDrag is finished
> it will call StopRouting which deletes the m_placer. The Wait() in
> performRouting will then return and it will crash as soon as it tries
> to access the m_placer.
>
> My fix is to add the InlineDrag action to IsCancelInteractive. I also
> added a wxCHECK2 call in case there are other ways for this to happen
> (at least it won't crash).
>
> To reproduce the bug (assuming standard hotkeys):
> 1. Press X to enter route mode.
> 2. Click on a trace.
> 3. With the cursor over a trace, press D to enter drag mode.
> 4. Click somewhere to quit drag mode.
> 5. (Back in routing mode) Click again to crash pcbnew.
>
> ---
> pcbnew/router/router_tool.cpp | 3 +++
> pcbnew/tools/tool_event_utils.cpp | 3 ++-
> 2 files changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/pcbnew/router/router_tool.cpp
> b/pcbnew/router/router_tool.cpp
> index 8f79cd0..5bfcc4c 100644
> --- a/pcbnew/router/router_tool.cpp
> +++ b/pcbnew/router/router_tool.cpp
> @@ -600,6 +600,9 @@ void ROUTER_TOOL::performRouting()
>
> while( OPT_TOOL_EVENT evt = Wait() )
> {
> + // Don't crash if IsCancelInteractive missed an operation that
> cancelled routing.
> + wxCHECK2( m_router->RoutingInProgress(), break );
> +
> if( evt->IsMotion() )
> {
> m_router->SetOrthoMode( evt->Modifier( MD_CTRL ) );
> diff --git a/pcbnew/tools/tool_event_utils.cpp
> b/pcbnew/tools/tool_event_utils.cpp
> index 7abe83a..7d4558c 100644
> --- a/pcbnew/tools/tool_event_utils.cpp
> +++ b/pcbnew/tools/tool_event_utils.cpp
> @@ -31,7 +31,8 @@ bool TOOL_EVT_UTILS::IsCancelInteractive( const
> TOOL_EVENT& aEvt )
> {
> return aEvt.IsAction( &ACTIONS::cancelInteractive )
> | | aEvt.IsActivate()
> - || aEvt.IsCancel();
> + || aEvt.IsCancel()
> + || aEvt.IsAction( &PCB_ACTIONS::routerInlineDrag );
> }
>
> bool TOOL_EVT_UTILS::IsRotateToolEvt( const TOOL_EVENT& aEvt )
> --
> 2.10.2
>
> _______________________________________________
> Mailing list: https://launchpad.net/~kicad-developers
> Post to : kicad-developers@xxxxxxxxxxxxxxxxxxx
> Unsubscribe : https://launchpad.net/~kicad-developers
> More help : https://help.launchpad.net/ListHelp