Fix crash when a renamed part is saved
The crash happened when during rename operation, when the original part buffer has been marked as deleted, but its memory was not yet freed. The renamed part was still using the original SCH_SCREEN object, which was freed together with the original part buffer.
This commit is contained in:
parent
6322c90c50
commit
6b9a286a85
|
@ -378,6 +378,8 @@ bool LIB_MANAGER::UpdatePartAfterRename( LIB_PART* aPart, const wxString& oldAli
|
||||||
wxCHECK( partBuf, false );
|
wxCHECK( partBuf, false );
|
||||||
|
|
||||||
LIB_PART* original = new LIB_PART( *partBuf->GetOriginal() );
|
LIB_PART* original = new LIB_PART( *partBuf->GetOriginal() );
|
||||||
|
// Save the screen object, so it is transferred to the new buffer
|
||||||
|
std::unique_ptr<SCH_SCREEN> screen = partBuf->RemoveScreen();
|
||||||
|
|
||||||
if( !libBuf.DeleteBuffer( partBuf ) )
|
if( !libBuf.DeleteBuffer( partBuf ) )
|
||||||
return false;
|
return false;
|
||||||
|
@ -386,6 +388,7 @@ bool LIB_MANAGER::UpdatePartAfterRename( LIB_PART* aPart, const wxString& oldAli
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
partBuf = libBuf.GetBuffer( aPart->GetName() );
|
partBuf = libBuf.GetBuffer( aPart->GetName() );
|
||||||
|
partBuf->SetScreen( std::move( screen ) );
|
||||||
wxCHECK( partBuf, false );
|
wxCHECK( partBuf, false );
|
||||||
partBuf->SetOriginal( original ); // part buffer takes ownership of pointer
|
partBuf->SetOriginal( original ); // part buffer takes ownership of pointer
|
||||||
|
|
||||||
|
@ -638,8 +641,8 @@ LIB_MANAGER::LIB_BUFFER& LIB_MANAGER::getLibraryBuffer( const wxString& aLibrary
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LIB_MANAGER::PART_BUFFER::PART_BUFFER( LIB_PART* aPart, SCH_SCREEN* aScreen )
|
LIB_MANAGER::PART_BUFFER::PART_BUFFER( LIB_PART* aPart, std::unique_ptr<SCH_SCREEN> aScreen )
|
||||||
: m_screen( aScreen ), m_part( aPart )
|
: m_screen( std::move( aScreen ) ), m_part( aPart )
|
||||||
{
|
{
|
||||||
m_original = new LIB_PART( *aPart );
|
m_original = new LIB_PART( *aPart );
|
||||||
}
|
}
|
||||||
|
@ -647,7 +650,6 @@ LIB_MANAGER::PART_BUFFER::PART_BUFFER( LIB_PART* aPart, SCH_SCREEN* aScreen )
|
||||||
|
|
||||||
LIB_MANAGER::PART_BUFFER::~PART_BUFFER()
|
LIB_MANAGER::PART_BUFFER::~PART_BUFFER()
|
||||||
{
|
{
|
||||||
delete m_screen;
|
|
||||||
delete m_part;
|
delete m_part;
|
||||||
delete m_original;
|
delete m_original;
|
||||||
}
|
}
|
||||||
|
@ -692,7 +694,8 @@ bool LIB_MANAGER::LIB_BUFFER::CreateBuffer( LIB_PART* aCopy, SCH_SCREEN* aScreen
|
||||||
{
|
{
|
||||||
wxASSERT( m_aliases.count( aCopy->GetName() ) == 0 ); // only for new parts
|
wxASSERT( m_aliases.count( aCopy->GetName() ) == 0 ); // only for new parts
|
||||||
wxASSERT( aCopy->GetLib() == nullptr );
|
wxASSERT( aCopy->GetLib() == nullptr );
|
||||||
auto partBuf = std::make_shared<PART_BUFFER>( aCopy, aScreen );
|
std::unique_ptr<SCH_SCREEN> screen( aScreen );
|
||||||
|
auto partBuf = std::make_shared<PART_BUFFER>( aCopy, std::move( screen ) );
|
||||||
m_parts.push_back( partBuf );
|
m_parts.push_back( partBuf );
|
||||||
addAliases( partBuf );
|
addAliases( partBuf );
|
||||||
|
|
||||||
|
|
|
@ -32,12 +32,12 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <wx/arrstr.h>
|
#include <wx/arrstr.h>
|
||||||
#include <lib_manager_adapter.h>
|
#include <lib_manager_adapter.h>
|
||||||
|
#include <class_sch_screen.h>
|
||||||
|
|
||||||
class LIB_ALIAS;
|
class LIB_ALIAS;
|
||||||
class LIB_PART;
|
class LIB_PART;
|
||||||
class LIB_BUFFER;
|
class LIB_BUFFER;
|
||||||
class PART_LIB;
|
class PART_LIB;
|
||||||
class SCH_SCREEN;
|
|
||||||
class SCH_PLUGIN;
|
class SCH_PLUGIN;
|
||||||
class LIB_EDIT_FRAME;
|
class LIB_EDIT_FRAME;
|
||||||
class SYMBOL_LIB_TABLE;
|
class SYMBOL_LIB_TABLE;
|
||||||
|
@ -289,7 +289,7 @@ private:
|
||||||
class PART_BUFFER
|
class PART_BUFFER
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PART_BUFFER( LIB_PART* aPart = nullptr, SCH_SCREEN* aScreen = nullptr );
|
PART_BUFFER( LIB_PART* aPart = nullptr, std::unique_ptr<SCH_SCREEN> aScreen = nullptr );
|
||||||
~PART_BUFFER();
|
~PART_BUFFER();
|
||||||
|
|
||||||
LIB_PART* GetPart() const { return m_part; }
|
LIB_PART* GetPart() const { return m_part; }
|
||||||
|
@ -299,13 +299,26 @@ private:
|
||||||
void SetOriginal( LIB_PART* aPart );
|
void SetOriginal( LIB_PART* aPart );
|
||||||
|
|
||||||
bool IsModified() const;
|
bool IsModified() const;
|
||||||
SCH_SCREEN* GetScreen() const { return m_screen; }
|
SCH_SCREEN* GetScreen() const { return m_screen.get(); }
|
||||||
|
|
||||||
|
///> Transfer the screen ownership
|
||||||
|
std::unique_ptr<SCH_SCREEN> RemoveScreen()
|
||||||
|
{
|
||||||
|
return std::move( m_screen );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetScreen( std::unique_ptr<SCH_SCREEN> aScreen )
|
||||||
|
{
|
||||||
|
bool ret = !!m_screen;
|
||||||
|
m_screen = std::move( aScreen );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
typedef std::shared_ptr<PART_BUFFER> PTR;
|
typedef std::shared_ptr<PART_BUFFER> PTR;
|
||||||
typedef std::weak_ptr<PART_BUFFER> WEAK_PTR;
|
typedef std::weak_ptr<PART_BUFFER> WEAK_PTR;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SCH_SCREEN* m_screen;
|
std::unique_ptr<SCH_SCREEN> m_screen;
|
||||||
|
|
||||||
///> Working copy
|
///> Working copy
|
||||||
LIB_PART* m_part;
|
LIB_PART* m_part;
|
||||||
|
|
Loading…
Reference in New Issue