Fix serious memory leak in schematic part library manager.

This commit is contained in:
Wayne Stambaugh 2015-02-06 10:34:11 -05:00
parent d52436aed8
commit 8f1addc1f8
3 changed files with 46 additions and 18 deletions

View File

@ -61,6 +61,9 @@ int LIB_PART::m_subpartIdSeparator = 0;
int LIB_PART::m_subpartFirstId = 'A'; int LIB_PART::m_subpartFirstId = 'A';
const wxChar traceSchLibMem[] = wxT( "KISCHLIBMEM" ); // public
LIB_ALIAS::LIB_ALIAS( const wxString& aName, LIB_PART* aRootPart ): LIB_ALIAS::LIB_ALIAS( const wxString& aName, LIB_PART* aRootPart ):
EDA_ITEM( LIB_ALIAS_T ), EDA_ITEM( LIB_ALIAS_T ),
shared( aRootPart ) shared( aRootPart )
@ -85,10 +88,10 @@ LIB_ALIAS::~LIB_ALIAS()
{ {
wxASSERT_MSG( shared, wxT( "~LIB_ALIAS() without a LIB_PART" ) ); wxASSERT_MSG( shared, wxT( "~LIB_ALIAS() without a LIB_PART" ) );
#if defined(DEBUG) && 1 wxLogTrace( traceSchLibMem,
printf( "%s: destroying alias:'%s' of part:'%s' alias count:%d.\n", wxT( "%s: destroying alias:'%s' of part:'%s'." ),
__func__, TO_UTF8( name ), TO_UTF8( shared->GetName() ), int( shared->m_aliases.size() ) ); GetChars( wxString::FromAscii( __WXFUNCTION__ ) ), GetChars( name ),
#endif GetChars( shared->GetName() ) );
if( shared ) if( shared )
shared->RemoveAlias( this ); shared->RemoveAlias( this );
@ -241,9 +244,10 @@ LIB_PART::LIB_PART( LIB_PART& aPart, PART_LIB* aLibrary ) :
LIB_PART::~LIB_PART() LIB_PART::~LIB_PART()
{ {
wxLogDebug( wxT( "%s: destroying part '%s' with alias list count of %d\n" ), wxLogTrace( traceSchLibMem,
wxT( "%s: destroying part '%s' with alias list count of %u." ),
GetChars( wxString::FromAscii( __WXFUNCTION__ ) ), GetChars( GetName() ), GetChars( wxString::FromAscii( __WXFUNCTION__ ) ), GetChars( GetName() ),
int( m_aliases.size() ) ); m_aliases.size() );
// If the part is being deleted directly rather than through the library, // If the part is being deleted directly rather than through the library,
// delete all of the aliases. // delete all of the aliases.
@ -481,7 +485,7 @@ void LIB_PART::RemoveDrawItem( LIB_ITEM* aItem, EDA_DRAW_PANEL* aPanel, wxDC* aD
{ {
wxASSERT( aItem != NULL ); wxASSERT( aItem != NULL );
// none of the MANDATOR_FIELDS may be removed in RAM, but they may be // none of the MANDATORY_FIELDS may be removed in RAM, but they may be
// omitted when saving to disk. // omitted when saving to disk.
if( aItem->Type() == LIB_FIELD_T ) if( aItem->Type() == LIB_FIELD_T )
{ {
@ -1692,10 +1696,13 @@ LIB_ALIAS* LIB_PART::RemoveAlias( LIB_ALIAS* aAlias )
{ {
bool rename = aAlias->IsRoot(); bool rename = aAlias->IsRoot();
DBG( printf( "%s: part:'%s' alias:'%s'\n", __func__, wxLogTrace( traceSchLibMem,
TO_UTF8( m_name ), wxT( "%s: part:'%s', alias:'%s', alias count %u, reference count %d." ),
TO_UTF8( aAlias->GetName() ) GetChars( wxString::FromAscii( __WXFUNCTION__ ) ),
);) GetChars( m_name ),
GetChars( aAlias->GetName() ),
m_aliases.size(),
m_me.use_count() );
it = m_aliases.erase( it ); it = m_aliases.erase( it );

View File

@ -1,9 +1,9 @@
/* /*
* 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) 2004 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net> * Copyright (C) 2008-2015 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors. * Copyright (C) 2004-2015 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
@ -34,6 +34,7 @@
#include <lib_draw_item.h> #include <lib_draw_item.h>
#include <lib_field.h> #include <lib_field.h>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
class LINE_READER; class LINE_READER;
class OUTPUTFORMATTER; class OUTPUTFORMATTER;
@ -69,6 +70,10 @@ enum LibrEntryOptions
}; };
/// WXTRACE value to enable schematic library memory deletion debug output.
extern const wxChar traceSchLibMem[];
/** /**
* Part library alias object definition. * Part library alias object definition.
* *
@ -153,7 +158,7 @@ public:
/** /**
* Function SaveDocs * Function SaveDocs
* rrite the entry document information to \a aFormatter in "*.dcm" format. * write the entry document information to \a aFormatter in "*.dcm" format.
* *
* @param aFormatter The #OUTPUTFORMATTER to write the alias documents to. * @param aFormatter The #OUTPUTFORMATTER to write the alias documents to.
* @return True if success writing else false. * @return True if success writing else false.

View File

@ -1,9 +1,9 @@
/* /*
* 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) 2004 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net> * Copyright (C) 2008-2015 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors. * Copyright (C) 2004-2015 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
@ -73,6 +73,22 @@ PART_LIB::PART_LIB( int aType, const wxString& aFileName ) :
PART_LIB::~PART_LIB() PART_LIB::~PART_LIB()
{ {
// When the library is destroyed, all of the alias objects on the heap should be deleted.
for( LIB_ALIAS_MAP::iterator it = m_amap.begin(); it != m_amap.end(); ++it )
{
wxLogTrace( traceSchLibMem, wxT( "Removing alias %s from library %s." ),
GetChars( it->second->GetName() ), GetChars( GetLogicalName() ) );
LIB_PART* part = it->second->GetPart();
LIB_ALIAS* alias = it->second;
delete alias;
// When the last alias of a part is destroyed, the part is no longer required and it
// too is destroyed.
if( part && part->GetAliasCount() == 0 )
delete part;
}
m_amap.clear();
} }