KiCad: fix segfault bug when switching from remote to local project.

* Deleting the wxFileSystemWatcher when switching from a remote project to
  a local project caused KiCad to segfault.  Switching from a local project
  to a remote project did not cause KiCad to crash.  The fix was to clear all
  of the file system watcher paths instead of deleting and creating a new file
  system watcher object between project changes.  The object still crashes on
  exit when deleted in the main window dtor.  Allocating the file system
  watcher object on the stack instead of on the heap did not make any difference.
This commit is contained in:
Wayne Stambaugh 2016-06-16 08:38:31 -04:00
parent 3f2b15711c
commit 66f8a0c1b5
1 changed files with 27 additions and 11 deletions

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors. * Copyright (C) 1992-2016 KiCad Developers, see change_log.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -154,7 +154,12 @@ TREE_PROJECT_FRAME::TREE_PROJECT_FRAME( KICAD_MANAGER_FRAME* parent ) :
TREE_PROJECT_FRAME::~TREE_PROJECT_FRAME() TREE_PROJECT_FRAME::~TREE_PROJECT_FRAME()
{ {
delete m_watcher; if( m_watcher )
{
m_watcher->RemoveAll();
m_watcher->SetOwner( NULL );
delete m_watcher;
}
} }
@ -212,8 +217,8 @@ void TREE_PROJECT_FRAME::OnCreateNewDirectory( wxCommandEvent& event )
curr_dir += wxFileName::GetPathSeparator(); curr_dir += wxFileName::GetPathSeparator();
} }
wxString msg = wxString::Format( _( "Current project directory:\n%s" ), GetChars( prj_dir ) ); wxString msg = wxString::Format( _( "Current project directory:\n%s" ), GetChars( prj_dir ) );
wxString subdir = wxGetTextFromUser( msg, _( "Create New Directory" ), curr_dir ); wxString subdir = wxGetTextFromUser( msg, _( "Create New Directory" ), curr_dir );
if( subdir.IsEmpty() ) if( subdir.IsEmpty() )
return; return;
@ -884,6 +889,7 @@ wxTreeItemId TREE_PROJECT_FRAME::findSubdirTreeItem( const wxString& aSubDir )
root_id = subdirs_id.top(); root_id = subdirs_id.top();
subdirs_id.pop(); subdirs_id.pop();
kid = m_TreeProject->GetFirstChild( root_id, cookie ); kid = m_TreeProject->GetFirstChild( root_id, cookie );
if( ! kid.IsOk() ) if( ! kid.IsOk() )
continue; continue;
} }
@ -903,6 +909,7 @@ wxTreeItemId TREE_PROJECT_FRAME::findSubdirTreeItem( const wxString& aSubDir )
if( itemData->IsPopulated() ) if( itemData->IsPopulated() )
subdirs_id.push( kid ); subdirs_id.push( kid );
} }
kid = m_TreeProject->GetNextChild( root_id, cookie ); kid = m_TreeProject->GetNextChild( root_id, cookie );
} }
@ -992,9 +999,15 @@ void TREE_PROJECT_FRAME::OnFileSystemEvent( wxFileSystemWatcherEvent& event )
void TREE_PROJECT_FRAME::FileWatcherReset() void TREE_PROJECT_FRAME::FileWatcherReset()
{ {
// Prepare file watcher: // Prepare file watcher:
delete m_watcher; if( m_watcher )
m_watcher = new wxFileSystemWatcher(); {
m_watcher->SetOwner( this ); m_watcher->RemoveAll();
}
else
{
m_watcher = new wxFileSystemWatcher();
m_watcher->SetOwner( this );
}
// Add directories which should be monitored. // Add directories which should be monitored.
// under windows, we add the curr dir and all subdirs // under windows, we add the curr dir and all subdirs
@ -1033,6 +1046,7 @@ void TREE_PROJECT_FRAME::FileWatcherReset()
root_id = subdirs_id.top(); root_id = subdirs_id.top();
subdirs_id.pop(); subdirs_id.pop();
kid = m_TreeProject->GetFirstChild( root_id, cookie ); kid = m_TreeProject->GetFirstChild( root_id, cookie );
if( !kid.IsOk() ) if( !kid.IsOk() )
continue; continue;
} }
@ -1045,7 +1059,7 @@ void TREE_PROJECT_FRAME::FileWatcherReset()
// we can see wxString under a debugger, not a wxFileName // we can see wxString under a debugger, not a wxFileName
wxString path = itemData->GetFileName(); wxString path = itemData->GetFileName();
DBG(printf( "%s: add '%s'\n", __func__, TO_UTF8( path ) );) wxLogDebug( "%s: add '%s'\n", __func__, TO_UTF8( path ) );
if( wxFileName::IsDirReadable( path ) ) // linux whines about watching protected dir if( wxFileName::IsDirReadable( path ) ) // linux whines about watching protected dir
{ {
@ -1065,13 +1079,15 @@ void TREE_PROJECT_FRAME::FileWatcherReset()
#if defined(DEBUG) && 1 #if defined(DEBUG) && 1
wxArrayString paths; wxArrayString paths;
m_watcher->GetWatchedPaths( &paths ); m_watcher->GetWatchedPaths( &paths );
printf( "%s: watched paths:\n", __func__ ); wxLogDebug( "%s: watched paths:", __func__ );
for( unsigned ii = 0; ii < paths.GetCount(); ii++ ) for( unsigned ii = 0; ii < paths.GetCount(); ii++ )
printf( " %s\n", TO_UTF8( paths[ii] ) ); wxLogDebug( " %s\n", TO_UTF8( paths[ii] ) );
#endif #endif
} }
void KICAD_MANAGER_FRAME::OnChangeWatchedPaths(wxCommandEvent& aEvent )
void KICAD_MANAGER_FRAME::OnChangeWatchedPaths( wxCommandEvent& aEvent )
{ {
m_LeftWin->FileWatcherReset(); m_LeftWin->FileWatcherReset();
} }