jpeg pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=d689afccaeceacd1f8e06e9d161ca7591a6a334f
commit d689afccaeceacd1f8e06e9d161ca7591a6a334f Author: Jean-Philippe Andre <[email protected]> Date: Wed Feb 15 20:07:11 2017 +0900 group: Track calls to group_del After a long search I found that fileselector was not calling super.group_del on deletion, leading to the use of dangling pointers. So let's verify that group_del is properly called. See T4598 --- src/lib/edje/edje_smart.c | 1 + src/lib/elementary/elm_widget.c | 1 + src/lib/emotion/emotion_smart.c | 2 +- src/lib/evas/canvas/efl_canvas_group.eo | 1 + src/lib/evas/canvas/evas_object_smart.c | 14 ++++++++++++++ src/lib/evas/canvas/evas_object_smart_clipped.c | 1 + src/lib/evas/include/evas_private.h | 2 +- 7 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/lib/edje/edje_smart.c b/src/lib/edje/edje_smart.c index 583e714..7af25b9 100644 --- a/src/lib/edje/edje_smart.c +++ b/src/lib/edje/edje_smart.c @@ -159,6 +159,7 @@ _edje_object_efl_canvas_group_group_del(Eo *obj, Edje *ed) _edje_clean_objects(ed); _edje_unref(ed); _edje_lib_unref(); + efl_canvas_group_del(efl_super(obj, MY_CLASS)); } EOLIAN static void diff --git a/src/lib/elementary/elm_widget.c b/src/lib/elementary/elm_widget.c index dd459bb..a070c4c 100644 --- a/src/lib/elementary/elm_widget.c +++ b/src/lib/elementary/elm_widget.c @@ -486,6 +486,7 @@ _elm_widget_efl_canvas_group_group_del(Eo *obj, Elm_Widget_Smart_Data *sd) eina_stringshare_del(sd->access_info); eina_stringshare_del(sd->accessible_name); evas_object_smart_data_set(obj, NULL); + efl_canvas_group_del(efl_super(obj, MY_CLASS)); } static void diff --git a/src/lib/emotion/emotion_smart.c b/src/lib/emotion/emotion_smart.c index 96f14da..42b5e35 100644 --- a/src/lib/emotion/emotion_smart.c +++ b/src/lib/emotion/emotion_smart.c @@ -1967,7 +1967,6 @@ _efl_canvas_video_efl_canvas_group_group_add(Evas_Object *obj, Efl_Canvas_Video_ EOLIAN static void _efl_canvas_video_efl_canvas_group_group_del(Evas_Object *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd) { - if (!sd) return; if (sd->engine_instance) { emotion_engine_instance_file_close(sd->engine_instance); @@ -1993,6 +1992,7 @@ _efl_canvas_video_efl_canvas_group_group_del(Evas_Object *obj EINA_UNUSED, Efl_C if (sd->smartobj) evas_object_smart_data_set(sd->smartobj, NULL); sd->smartobj = NULL; EINA_REFCOUNT_UNREF(sd) _smart_data_free(sd); + efl_canvas_group_del(efl_super(obj, MY_CLASS)); } EOLIAN static void diff --git a/src/lib/evas/canvas/efl_canvas_group.eo b/src/lib/evas/canvas/efl_canvas_group.eo index b28b5c9..2eda28e 100644 --- a/src/lib/evas/canvas/efl_canvas_group.eo +++ b/src/lib/evas/canvas/efl_canvas_group.eo @@ -109,6 +109,7 @@ class Efl.Canvas.Group (Efl.Canvas.Object) class.constructor; class.destructor; Efl.Object.constructor; + Efl.Object.destructor; Efl.Canvas.Object.no_render { set; } Efl.Canvas.Object.paragraph_direction { get; set; } } diff --git a/src/lib/evas/canvas/evas_object_smart.c b/src/lib/evas/canvas/evas_object_smart.c index 7238069..6450d2b 100644 --- a/src/lib/evas/canvas/evas_object_smart.c +++ b/src/lib/evas/canvas/evas_object_smart.c @@ -49,6 +49,7 @@ struct _Evas_Smart_Data Eina_Bool deletions_waiting : 1; Eina_Bool need_recalculate : 1; Eina_Bool update_boundingbox_needed : 1; + Eina_Bool group_del_called : 1; }; typedef struct @@ -526,6 +527,7 @@ _efl_canvas_group_group_members_all_del(Evas_Object *eo_obj) { evas_object_del((Evas_Object *)((Evas_Object_Protected_Data *)memobj->object)); } + o->group_del_called = EINA_TRUE; } static void @@ -627,6 +629,17 @@ _efl_canvas_group_efl_object_constructor(Eo *eo_obj, Evas_Smart_Data *class_data return eo_obj; } +EOLIAN static void +_efl_canvas_group_efl_object_destructor(Eo *eo_obj, Evas_Smart_Data *o) +{ + efl_destructor(efl_super(eo_obj, MY_CLASS)); + if (!o->group_del_called) + { + ERR("efl_canvas_group_del() was not called on this object: %p (%s)", + eo_obj, efl_class_name_get(eo_obj)); + } +} + EAPI void evas_object_smart_move_children_relative(Eo *eo_obj, Evas_Coord dx, Evas_Coord dy) { @@ -662,6 +675,7 @@ _efl_canvas_group_group_add(Eo *eo_obj, Evas_Smart_Data *o EINA_UNUSED) EOLIAN static void _efl_canvas_group_group_del(Eo *eo_obj EINA_UNUSED, Evas_Smart_Data *o EINA_UNUSED) { + o->group_del_called = EINA_TRUE; } EOLIAN static void diff --git a/src/lib/evas/canvas/evas_object_smart_clipped.c b/src/lib/evas/canvas/evas_object_smart_clipped.c index 252709a..a4b96d3 100644 --- a/src/lib/evas/canvas/evas_object_smart_clipped.c +++ b/src/lib/evas/canvas/evas_object_smart_clipped.c @@ -79,6 +79,7 @@ EOLIAN static void _efl_canvas_group_clipped_efl_canvas_group_group_del(Eo *eo_obj, Evas_Object_Smart_Clipped_Data *obj EINA_UNUSED) { evas_object_smart_clipped_smart_del(eo_obj); + // group_del_called was already set to true, no need to call super here. } static void diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 7360391..a62852a 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1674,7 +1674,7 @@ void *evas_object_smart_render_cache_get(const Evas_Object *eo_obj); void evas_object_smart_render_cache_set(Evas_Object *eo_obj, void *data); const Eina_Inlist *evas_object_smart_members_get_direct(const Evas_Object *obj); -void _efl_canvas_group_group_members_all_del(Evas_Object *obj); +void _efl_canvas_group_group_members_all_del(Evas_Object *eo_obj); void _evas_object_smart_xy_update(Eo *eo_obj, Evas_Coord *px, Evas_Coord *py, Evas_Coord x, Evas_Coord y); void evas_call_smarts_calculate(Evas *e); void evas_object_smart_bounding_box_update(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); --
