Valgrind detected TextureSet leak and invalid access 50/117850/4
authorNick Holland <nick.holland@partner.samsung.com>
Tue, 28 Mar 2017 10:41:04 +0000 (11:41 +0100)
committerNick Holland <nick.holland@partner.samsung.com>
Tue, 28 Mar 2017 10:41:04 +0000 (11:41 +0100)
Memory leak:

If a public API TextureSet gets deleted, it sends a
message to update-manager (RemoveTextureSet).
The scene graph side TextureSet gets removed from
update manager, but it never gets deleted.

Invalid memory access:

Currently when a scene graph TextureSet gets deleted
the renderers using that TextureSet are not notified.

So when a Render gets deleted it would call
TextureSet->RemoveObserver( this );

on an already deleted TextureSet.

DALi however doesn't crash at this point,
because the TextureSet is stored in a memory
 pool so the object is still reachable.

Change-Id: Icf0f5a3e55d3ba7537f40db08accad04ae4440f7

dali/internal/update/manager/update-manager.cpp
dali/internal/update/rendering/scene-graph-renderer.cpp
dali/internal/update/rendering/scene-graph-renderer.h
dali/internal/update/rendering/scene-graph-texture-set.cpp

index 8cd9021a99ea1ae6efb6f5595da96ac363eb5be9..dae719408d94c83546eeb8ecc106e5e98e586dba 100644 (file)
@@ -631,6 +631,9 @@ void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
     if( textureSet == mImpl->textureSets[i] )
     {
       mImpl->textureSets.Remove( mImpl->textureSets.Begin() + i );
+
+      // Update manager has ownership of the TextureSet
+      delete textureSet;
       return;
     }
   }
index af7d93e0eba819e34421059aac6f67c4b5ebde5c..732ca235803e9c8db9895164ade58346974863e8 100644 (file)
@@ -656,6 +656,12 @@ void Renderer::TextureSetChanged()
   mResendFlag |= RESEND_DATA_PROVIDER;
 }
 
+void Renderer::TextureSetDeleted()
+{
+  mTextureSet = NULL;
+
+  mResendFlag |= RESEND_DATA_PROVIDER;
+}
 void Renderer::ConnectionsChanged( PropertyOwner& object )
 {
   // One of our child objects has changed it's connections. Ensure the uniform
@@ -679,11 +685,7 @@ void Renderer::UniformMappingsChanged( const UniformMap& mappings )
 
 void Renderer::ObservedObjectDestroyed(PropertyOwner& owner)
 {
-  if( reinterpret_cast<PropertyOwner*>(mTextureSet) == &owner )
-  {
-    mTextureSet = NULL;
-  }
-  else if( reinterpret_cast<PropertyOwner*>(mShader) == &owner )
+  if( reinterpret_cast<PropertyOwner*>(mShader) == &owner )
   {
     mShader = NULL;
   }
index aa530e1ef93e69d1a3a52984221b0abe9de73ae1..ea1308bfdc12752b700b2fe3f3769b3cc9d8a75b 100644 (file)
@@ -277,6 +277,11 @@ public:
    */
   void TextureSetChanged();
 
+  /**
+   * Called by the TextureSet to notify to the renderer that it is about to be deleted
+   */
+  void TextureSetDeleted();
+
 public: // Implementation of ObjectOwnerContainer template methods
   /**
    * Connect the object to the scene graph
index 65aa91302b5c6913fb30176543d7602cba679a8e..a5e7df877fb38b664796216f0783e20833c0c415 100644 (file)
@@ -51,6 +51,11 @@ TextureSet::TextureSet()
 
 TextureSet::~TextureSet()
 {
+  size_t rendererCount = mRenderers.Size();
+  for( size_t i(0); i<rendererCount; ++i )
+  {
+    mRenderers[i]->TextureSetDeleted();
+  }
 }
 
 void TextureSet::operator delete( void* ptr )