Page MenuHomePhabricator

evas objects leaking in some cases
Closed, ResolvedPublic

Description

I discovered today that some evas objects never get destroyed when they have 0 refcount (evas_object_refs) and evas_object_del is called on them.

This is also extremely simple to reproduce:

  • Menu->Desktop->Add bryce
  • Right click the clock gadget
  • Dismiss popup (press escape or click desktop)
  • Popup is never destroyed

The mechanism for managing this popup is used many places in Enlightenment, and it seems to work as expected for the rest of the cases; evas_object_ref is called on hide to preserve the object while it animates, and then evas_object_unref is called at the end of _e_comp_object_util_done_defer to remove the final ref after the object is fully hidden.

In this particular case, however, the eo obj->refcount is still >0 while the evas object refcount == 0, and the object is never destroyed.

Help? :)

EDIT: also I tested this with a version of EFL from early May and the issue is still there, so I guess this is a longstanding internal issue

zmike created this task.Oct 17 2016, 10:23 AM

I think we descovered something similar @raster

Raster did a little hack so they are not blocking The evas shutdown ...

Also some note:

There have been changes to the deletion of a Evas object, if something gets deleted and has still children the children are reparented to the canvas.

So for example: if you have a evas box with 5 children an you delete the box, the children will survive.

Okay just noticed that you explicitly called del on the objects so forget the lower part :)

evas_object_ref(and unref) were never intended to keep an object VISIBLE after deletion simply to keep object lifetime around longer to access data on an object etc. - so using it as a way to keep it visible is fundamentally against the design and why my changes to hide it on del created trouble for you.

if you want things to stay alive for hiding animations... then delay the del until the animation is done. that's how i have always done this and it's always worked. dont use the ref/unref for this. it was not intended for this at all as a del could stop all animation and delete internal objects even tho parent obj still has a ref and is alive - it's been told to begin it's death even if kept alive by a ref.

zmike added a comment.Oct 19 2016, 7:09 AM
In T4740#73200, @raster wrote:

evas_object_ref(and unref) were never intended to keep an object VISIBLE after deletion simply to keep object lifetime around longer to access data on an object etc. - so using it as a way to keep it visible is fundamentally against the design and why my changes to hide it on del created trouble for you.

if you want things to stay alive for hiding animations... then delay the del until the animation is done. that's how i have always done this and it's always worked. dont use the ref/unref for this. it was not intended for this at all as a del could stop all animation and delete internal objects even tho parent obj still has a ref and is alive - it's been told to begin it's death even if kept alive by a ref.

This ticket is not related to any of the issues you've cited. The mechanism described was written based on the exact workings of evas ca. 2013; there's no use claiming evas should have worked one way or another, it's not an application developer's job to instinctively know the full history of the scenegraph design.

The fact that such a massive regression went unnoticed for so many years makes changing the underlying behavior extremely difficult, especially considering how many products and projects which have now shipped which will break entirely if changes are made.

Please create a new ticket if you want to continue discussing this unrelated topic, I'd prefer to keep things relevant since this appears to be an extremely tricky bug to track down.

zmike added a comment.Oct 19 2016, 7:54 AM

This issue occurs any time an eo call fails to resolve:

#0  0x00007fe79c80438f in _efl_ref (obj=0x25b2e20) at lib/eo/eo_private.h:307
#1  0x00007fe79c8060c0 in _efl_object_call_resolve (eo_id=0x400000071aca9f18, func_name=0x7fe7a6038630 "elm_obj_widget_tree_unfocusable_set", call=0x7fff0492d1b0, cache=0x7fe7a63e9e80, file=0x7fe7a6038538 "lib/elementary/elm_widget.eo.c", line=101) at lib/eo/eo.c:377

This ref is never removed, and so the object can never be deleted.