From 850a22c3ae96bc07ed8f54fde329c985270d7564 Mon Sep 17 00:00:00 2001 From: Marek Roszko Date: Sat, 1 May 2021 12:46:18 -0400 Subject: [PATCH] Try/catch gerber file loading in attempt to catch oom Potentially help with #7444 --- gerbview/files.cpp | 78 +++++++++++++++++++++++++------------------ gerbview/readgerb.cpp | 9 +++-- 2 files changed, 51 insertions(+), 36 deletions(-) diff --git a/gerbview/files.cpp b/gerbview/files.cpp index 982c961586..216f3081aa 100644 --- a/gerbview/files.cpp +++ b/gerbview/files.cpp @@ -37,7 +37,8 @@ // HTML Messages used more than one time: #define MSG_NO_MORE_LAYER _( "No more available layers in GerbView to load files" ) -#define MSG_NOT_LOADED _( "\nNot loaded: %s" ) +#define MSG_NOT_LOADED _( "\nNot loaded: %s" ) +#define MSG_OOM _( "\nMemory was exhausted reading: %s" ) void GERBVIEW_FRAME::OnGbrFileHistory( wxCommandEvent& event ) @@ -253,48 +254,59 @@ bool GERBVIEW_FRAME::LoadListOfGerberAndDrillFiles( const wxString& aPath, visibility[ layer ] = true; - if( aFileType && (*aFileType)[ii] == 1 ) + try { - LoadExcellonFiles( filename.GetFullPath() ); - layer = GetActiveLayer(); // Loading NC drill file changes the active layer - } - else - { - if( filename.GetExt() == GerberJobFileExtension.c_str() ) + if( aFileType && ( *aFileType )[ii] == 1 ) { - //We cannot read a gerber job file as a gerber plot file: skip it - wxString txt; - txt.Printf( - _( "A gerber job file cannot be loaded as a plot file %s" ), - filename.GetFullName() ); - success = false; - reporter.Report( txt, RPT_SEVERITY_ERROR ); + LoadExcellonFiles( filename.GetFullPath() ); + layer = GetActiveLayer(); // Loading NC drill file changes the active layer } - else if( Read_GERBER_File( filename.GetFullPath() ) ) + else { - UpdateFileHistory( m_lastFileName ); - - layer = getNextAvailableLayer( layer ); - - if( layer == NO_AVAILABLE_LAYERS && ii < aFilenameList.GetCount()-1 ) + if( filename.GetExt() == GerberJobFileExtension.c_str() ) { + //We cannot read a gerber job file as a gerber plot file: skip it + wxString txt; + txt.Printf( _( "A gerber job file cannot be loaded as a plot file " + "%s" ), + filename.GetFullName() ); success = false; - reporter.Report( MSG_NO_MORE_LAYER, RPT_SEVERITY_ERROR ); - - // Report the name of not loaded files: - ii += 1; - while( ii < aFilenameList.GetCount() ) - { - filename = aFilenameList[ii++]; - wxString txt = wxString::Format( MSG_NOT_LOADED, filename.GetFullName() ); - reporter.Report( txt, RPT_SEVERITY_ERROR ); - } - break; + reporter.Report( txt, RPT_SEVERITY_ERROR ); } + else if( Read_GERBER_File( filename.GetFullPath() ) ) + { + UpdateFileHistory( m_lastFileName ); - SetActiveLayer( layer, false ); + layer = getNextAvailableLayer( layer ); + + if( layer == NO_AVAILABLE_LAYERS && ii < aFilenameList.GetCount() - 1 ) + { + success = false; + reporter.Report( MSG_NO_MORE_LAYER, RPT_SEVERITY_ERROR ); + + // Report the name of not loaded files: + ii += 1; + while( ii < aFilenameList.GetCount() ) + { + filename = aFilenameList[ii++]; + wxString txt = + wxString::Format( MSG_NOT_LOADED, filename.GetFullName() ); + reporter.Report( txt, RPT_SEVERITY_ERROR ); + } + break; + } + + SetActiveLayer( layer, false ); + } } } + catch( const std::bad_alloc& ) + { + wxString txt = wxString::Format( MSG_OOM, filename.GetFullName() ); + reporter.Report( txt, RPT_SEVERITY_ERROR ); + success = false; + continue; + } if( progress ) progress->AdvanceProgress(); diff --git a/gerbview/readgerb.cpp b/gerbview/readgerb.cpp index 680c49edcb..86ba0bb950 100644 --- a/gerbview/readgerb.cpp +++ b/gerbview/readgerb.cpp @@ -50,20 +50,23 @@ bool GERBVIEW_FRAME::Read_GERBER_File( const wxString& GERBER_FullFileName ) Erase_Current_DrawLayer( false ); } - gerber = new GERBER_FILE_IMAGE( layer ); + // use an unique ptr while we load to free on exception properly + std::unique_ptr gerber_uptr = std::make_unique( layer ); // Read the gerber file. The image will be added only if it can be read // to avoid broken data. - bool success = gerber->LoadGerberFile( GERBER_FullFileName ); + bool success = gerber_uptr->LoadGerberFile( GERBER_FullFileName ); if( !success ) { - delete gerber; + gerber_uptr.reset(); msg.Printf( _( "File \"%s\" not found" ), GERBER_FullFileName ); ShowInfoBarError( msg ); return false; } + gerber = gerber_uptr.release(); + wxASSERT( gerber != nullptr ); images->AddGbrImage( gerber, layer ); // Display errors list