← Back to team overview

kicad-developers team mailing list archive

wxFileSystemWatcher bug.

 

I found a nasty wxFileSystemWatcher bug on windows (and possibly other
platforms) when switching between a project on a mapped network drive to
a project on a local drive.  This crashes kicad every time.  It doesn't
crash when switching from a local drive to a mapped network drive.  I
fixed the project switching crash by not deleting and creating a new
m_watcher object every time a project is loaded.  However, kicad still
segfaults when running in gdb in the tree view window dtor when the
m_watcher object is deleted.  I tried disconnecting and unlinking the
event handler with no luck.  The only thing I didn't try was allocating
m_watcher on the stack rather than the heap which I would prefer not to
do.  Before I commit this patch, could I get one of our OSX devs and
Linux devs to test this patch to make sure it doesn't break anything on
these platforms.  If you could test the current code by switching
between remote and local projects to see if it crashes, that would
useful information to have as well.

Thanks,

Wayne
=== modified file 'kicad/tree_project_frame.cpp'
--- kicad/tree_project_frame.cpp	2016-04-12 15:50:42 +0000
+++ kicad/tree_project_frame.cpp	2016-06-14 13:55:26 +0000
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@xxxxxxxxxxx>
  * 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
  * modify it under the terms of the GNU General Public License
@@ -154,7 +154,12 @@
 
 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 @@
             curr_dir += wxFileName::GetPathSeparator();
     }
 
-    wxString    msg = wxString::Format( _( "Current project directory:\n%s" ), GetChars( prj_dir ) );
-    wxString    subdir = wxGetTextFromUser( msg, _( "Create New Directory" ), curr_dir );
+    wxString  msg = wxString::Format( _( "Current project directory:\n%s" ), GetChars( prj_dir ) );
+    wxString  subdir = wxGetTextFromUser( msg, _( "Create New Directory" ), curr_dir );
 
     if( subdir.IsEmpty() )
         return;
@@ -884,6 +889,7 @@
                 root_id = subdirs_id.top();
                 subdirs_id.pop();
                 kid = m_TreeProject->GetFirstChild( root_id, cookie );
+
                 if( ! kid.IsOk() )
                     continue;
             }
@@ -903,6 +909,7 @@
             if( itemData->IsPopulated() )
                 subdirs_id.push( kid );
         }
+
         kid = m_TreeProject->GetNextChild( root_id, cookie );
     }
 
@@ -992,9 +999,15 @@
 void TREE_PROJECT_FRAME::FileWatcherReset()
 {
     // Prepare file watcher:
-    delete m_watcher;
-    m_watcher = new wxFileSystemWatcher();
-    m_watcher->SetOwner( this );
+    if( m_watcher )
+    {
+        m_watcher->RemoveAll();
+    }
+    else
+    {
+        m_watcher = new wxFileSystemWatcher();
+        m_watcher->SetOwner( this );
+    }
 
     // Add directories which should be monitored.
     // under windows, we add the curr dir and all subdirs
@@ -1033,6 +1046,7 @@
                 root_id = subdirs_id.top();
                 subdirs_id.pop();
                 kid = m_TreeProject->GetFirstChild( root_id, cookie );
+
                 if( !kid.IsOk() )
                     continue;
             }
@@ -1045,7 +1059,7 @@
             // we can see wxString under a debugger, not a wxFileName
             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
             {
@@ -1065,13 +1079,15 @@
 #if defined(DEBUG) && 1
     wxArrayString paths;
     m_watcher->GetWatchedPaths( &paths );
-    printf( "%s: watched paths:\n", __func__ );
+    wxLogDebug( "%s: watched paths:", __func__ );
+
     for( unsigned ii = 0; ii < paths.GetCount(); ii++ )
-        printf( " %s\n", TO_UTF8( paths[ii] ) );
+        wxLogDebug( " %s\n", TO_UTF8( paths[ii] ) );
 #endif
 }
 
-void KICAD_MANAGER_FRAME::OnChangeWatchedPaths(wxCommandEvent& aEvent )
+
+void KICAD_MANAGER_FRAME::OnChangeWatchedPaths( wxCommandEvent& aEvent )
 {
     m_LeftWin->FileWatcherReset();
 }


Follow ups