[3.0] Valgrind detected TextureSet leak and invalid access 38/121938/1
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>
Wed, 29 Mar 2017 10:49:23 +0000 (11:49 +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 d060699..1df67d3 100644 (file)
@@ -638,6 +638,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 75df93d..a097d8c 100644 (file)
@@ -655,6 +655,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
@@ -678,11 +684,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 a68db0f..4d90301 100644 (file)
@@ -269,6 +269,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 90554a1..ab5ff1b 100644 (file)
@@ -58,6 +58,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 )