KiCad: fix crash when kiface libraries are missing. (fixes lp:1577786)
* An assumption was made that wxDynamicLibrary.Load() would always result in a wxLogSystemError on failure which was not always true. The code now throws an exception which is caught by KiCad and an error message is displayed. In the case where the wxLogSystemError is shown, there will be an annoying two error messages but that is better than a crash.
This commit is contained in:
parent
b7ec4ea160
commit
21595f48d3
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
* Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||||
* Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
|
* Copyright (C) 2014-2016 KiCad Developers, see CHANGELOG.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
|
||||||
|
@ -62,7 +62,7 @@ KIWAY::KIWAY( PGM_BASE* aProgram, int aCtlBits, wxFrame* aTop ):
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Any event types derived from wxCommandEvt, like wxWindowDestroyEvent, are
|
// Any event types derived from wxCommandEvt, like wxWindowDestroyEvent, are
|
||||||
// propogated upwards to parent windows if not handled below. Therefore the
|
// propagated upwards to parent windows if not handled below. Therefore the
|
||||||
// m_top window should receive all wxWindowDestroyEvents originating from
|
// m_top window should receive all wxWindowDestroyEvents originating from
|
||||||
// KIWAY_PLAYERs. It does anyways, but now player_destroy_handler eavesdrops
|
// KIWAY_PLAYERs. It does anyways, but now player_destroy_handler eavesdrops
|
||||||
// on that event stream looking for KIWAY_PLAYERs being closed.
|
// on that event stream looking for KIWAY_PLAYERs being closed.
|
||||||
|
@ -74,6 +74,7 @@ void KIWAY::player_destroy_handler( wxWindowDestroyEvent& event )
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void KIWAY::SetTop( wxFrame* aTop )
|
void KIWAY::SetTop( wxFrame* aTop )
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -153,6 +154,8 @@ KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
|
||||||
if( m_kiface[aFaceId] )
|
if( m_kiface[aFaceId] )
|
||||||
return m_kiface[aFaceId];
|
return m_kiface[aFaceId];
|
||||||
|
|
||||||
|
wxString msg;
|
||||||
|
|
||||||
// DSO with KIFACE has not been loaded yet, does caller want to load it?
|
// DSO with KIFACE has not been loaded yet, does caller want to load it?
|
||||||
if( doLoad )
|
if( doLoad )
|
||||||
{
|
{
|
||||||
|
@ -165,15 +168,24 @@ KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
|
||||||
if( !dso.Load( dname, wxDL_VERBATIM | wxDL_NOW | wxDL_GLOBAL ) )
|
if( !dso.Load( dname, wxDL_VERBATIM | wxDL_NOW | wxDL_GLOBAL ) )
|
||||||
{
|
{
|
||||||
// Failure: error reporting UI was done via wxLogSysError().
|
// Failure: error reporting UI was done via wxLogSysError().
|
||||||
// No further reporting required here.
|
// No further reporting required here. Apparently this is not true on all
|
||||||
}
|
// platforms and/or wxWidgets builds and KiCad will crash. Throwing the exception
|
||||||
|
// here and catching it in the KiCad launcher resolves the crash issue. See bug
|
||||||
|
// report https://bugs.launchpad.net/kicad/+bug/1577786.
|
||||||
|
|
||||||
|
msg.Printf( _( "Failed to load kiface library '%s'." ), GetChars( dname ) );
|
||||||
|
THROW_IO_ERROR( msg );
|
||||||
|
}
|
||||||
else if( ( addr = dso.GetSymbol( wxT( KIFACE_INSTANCE_NAME_AND_VERSION ) ) ) == NULL )
|
else if( ( addr = dso.GetSymbol( wxT( KIFACE_INSTANCE_NAME_AND_VERSION ) ) ) == NULL )
|
||||||
{
|
{
|
||||||
// Failure: error reporting UI was done via wxLogSysError().
|
// Failure: error reporting UI was done via wxLogSysError().
|
||||||
// No further reporting required here.
|
// No further reporting required here. Assume the same thing applies here as
|
||||||
|
// above with the Load() call. This has not been tested.
|
||||||
|
msg.Printf(
|
||||||
|
_( "Could not read instance name and version symbol form kiface library '%s'." ),
|
||||||
|
GetChars( dname ) );
|
||||||
|
THROW_IO_ERROR( msg );
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
KIFACE_GETTER_FUNC* getter = (KIFACE_GETTER_FUNC*) addr;
|
KIFACE_GETTER_FUNC* getter = (KIFACE_GETTER_FUNC*) addr;
|
||||||
|
@ -182,7 +194,7 @@ KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
|
||||||
|
|
||||||
// KIFACE_GETTER_FUNC function comment (API) says the non-NULL is unconditional.
|
// KIFACE_GETTER_FUNC function comment (API) says the non-NULL is unconditional.
|
||||||
wxASSERT_MSG( kiface,
|
wxASSERT_MSG( kiface,
|
||||||
wxT( "attempted DSO has a bug, failed to return a KIFACE*" ) );
|
wxT( "attempted DSO has a bug, failed to return a KIFACE*" ) );
|
||||||
|
|
||||||
// Give the DSO a single chance to do its "process level" initialization.
|
// Give the DSO a single chance to do its "process level" initialization.
|
||||||
// "Process level" specifically means stay away from any projects in there.
|
// "Process level" specifically means stay away from any projects in there.
|
||||||
|
@ -203,16 +215,16 @@ KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
|
||||||
// to exist, and we did not find one. If we do not find one, this is an
|
// to exist, and we did not find one. If we do not find one, this is an
|
||||||
// installation bug.
|
// installation bug.
|
||||||
|
|
||||||
wxString msg = wxString::Format( wxT(
|
msg = wxString::Format( _(
|
||||||
"Fatal Installation Bug. File:\n"
|
"Fatal Installation Bug. File:\n"
|
||||||
"'%s'\ncould not be loaded\n" ), GetChars( dname ) );
|
"'%s'\ncould not be loaded\n" ), GetChars( dname ) );
|
||||||
|
|
||||||
if( ! wxFileExists( dname ) )
|
if( ! wxFileExists( dname ) )
|
||||||
msg << wxT( "It is missing.\n" );
|
msg << _( "It is missing.\n" );
|
||||||
else
|
else
|
||||||
msg << wxT( "Perhaps a shared library (.dll or .so) file is missing.\n" );
|
msg << _( "Perhaps a shared library (.dll or .so) file is missing.\n" );
|
||||||
|
|
||||||
msg << wxT( "From command line: argv[0]:\n'" );
|
msg << _( "From command line: argv[0]:\n'" );
|
||||||
msg << wxStandardPaths::Get().GetExecutablePath() << wxT( "'\n" );
|
msg << wxStandardPaths::Get().GetExecutablePath() << wxT( "'\n" );
|
||||||
|
|
||||||
// This is a fatal error, one from which we cannot recover, nor do we want
|
// This is a fatal error, one from which we cannot recover, nor do we want
|
||||||
|
@ -276,7 +288,6 @@ KIWAY_PLAYER* KIWAY::GetPlayerFrame( FRAME_T aFrameType )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate, KIWAY_PLAYER* aParent )
|
KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate, KIWAY_PLAYER* aParent )
|
||||||
{
|
{
|
||||||
// Since this will be called from python, cannot assume that code will
|
// Since this will be called from python, cannot assume that code will
|
||||||
|
@ -442,4 +453,3 @@ void KIWAY::OnKiwayEnd()
|
||||||
m_kiface[i]->OnKifaceEnd();
|
m_kiface[i]->OnKifaceEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -299,7 +299,16 @@ void KICAD_MANAGER_FRAME::RunEeschema( const wxString& aProjectSchematicFileName
|
||||||
// and the dialog field editor was used
|
// and the dialog field editor was used
|
||||||
if( !frame )
|
if( !frame )
|
||||||
{
|
{
|
||||||
frame = Kiway.Player( FRAME_SCH, true );
|
try
|
||||||
|
{
|
||||||
|
frame = Kiway.Player( FRAME_SCH, true );
|
||||||
|
}
|
||||||
|
catch( IO_ERROR err )
|
||||||
|
{
|
||||||
|
wxMessageBox( _( "Eeschema failed to load:\n" ) + err.errorText,
|
||||||
|
_( "KiCad Error" ), wxOK | wxICON_ERROR, this );
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !frame->IsShown() ) // the frame exists, (created by the dialog field editor)
|
if( !frame->IsShown() ) // the frame exists, (created by the dialog field editor)
|
||||||
|
@ -334,7 +343,17 @@ void KICAD_MANAGER_FRAME::OnRunSchLibEditor( wxCommandEvent& event )
|
||||||
|
|
||||||
if( !frame )
|
if( !frame )
|
||||||
{
|
{
|
||||||
frame = Kiway.Player( FRAME_SCH_LIB_EDITOR, true );
|
try
|
||||||
|
{
|
||||||
|
frame = Kiway.Player( FRAME_SCH_LIB_EDITOR, true );
|
||||||
|
}
|
||||||
|
catch( IO_ERROR err )
|
||||||
|
{
|
||||||
|
wxMessageBox( _( "Component library editor failed to load:\n" ) + err.errorText,
|
||||||
|
_( "KiCad Error" ), wxOK | wxICON_ERROR, this );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// frame->OpenProjectFiles( std::vector<wxString>( 1, aProjectSchematicFileName ) );
|
// frame->OpenProjectFiles( std::vector<wxString>( 1, aProjectSchematicFileName ) );
|
||||||
frame->Show( true );
|
frame->Show( true );
|
||||||
}
|
}
|
||||||
|
@ -349,7 +368,18 @@ void KICAD_MANAGER_FRAME::OnRunSchLibEditor( wxCommandEvent& event )
|
||||||
|
|
||||||
void KICAD_MANAGER_FRAME::RunPcbNew( const wxString& aProjectBoardFileName )
|
void KICAD_MANAGER_FRAME::RunPcbNew( const wxString& aProjectBoardFileName )
|
||||||
{
|
{
|
||||||
KIWAY_PLAYER* frame = Kiway.Player( FRAME_PCB, true );
|
KIWAY_PLAYER* frame;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
frame = Kiway.Player( FRAME_PCB, true );
|
||||||
|
}
|
||||||
|
catch( IO_ERROR err )
|
||||||
|
{
|
||||||
|
wxMessageBox( _( "Pcbnew failed to load:\n" ) + err.errorText, _( "KiCad Error" ),
|
||||||
|
wxOK | wxICON_ERROR, this );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// a pcb frame can be already existing, but not yet used.
|
// a pcb frame can be already existing, but not yet used.
|
||||||
// this is the case when running the footprint editor, or the footprint viewer first
|
// this is the case when running the footprint editor, or the footprint viewer first
|
||||||
|
@ -386,7 +416,17 @@ void KICAD_MANAGER_FRAME::OnRunPcbFpEditor( wxCommandEvent& event )
|
||||||
|
|
||||||
if( !frame )
|
if( !frame )
|
||||||
{
|
{
|
||||||
frame = Kiway.Player( FRAME_PCB_MODULE_EDITOR, true );
|
try
|
||||||
|
{
|
||||||
|
frame = Kiway.Player( FRAME_PCB_MODULE_EDITOR, true );
|
||||||
|
}
|
||||||
|
catch( IO_ERROR err )
|
||||||
|
{
|
||||||
|
wxMessageBox( _( "Footprint library editor failed to load:\n" ) + err.errorText,
|
||||||
|
_( "KiCad Error" ), wxOK | wxICON_ERROR, this );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// frame->OpenProjectFiles( std::vector<wxString>( 1, aProjectBoardFileName ) );
|
// frame->OpenProjectFiles( std::vector<wxString>( 1, aProjectBoardFileName ) );
|
||||||
frame->Show( true );
|
frame->Show( true );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue