GNOME Bugzilla – Bug 705739
Crash when removing a ClutterActor from a scene at the end of an animation
Last modified: 2013-08-19 23:25:43 UTC
Not knowing much about what's going on in the glue between native object and js proxies :( Here is the program to reproduce : ---------------------------------------------------------------- const Lang = imports.lang; const Mainloop = imports.mainloop; const Clutter = imports.gi.Clutter; Clutter.init(null, null); let stage = new Clutter.Stage({ width: 200, height: 200, }); stage.connect('destroy', Clutter.main_quit); stage.add_child(new Clutter.Actor({ width: 200, height: 200, background_color: new Clutter.Color({ red: 0xff, green: 0, blue: 0, alpha: 0xff, }), })); Mainloop.timeout_add(2000, Lang.bind(this, function() { let children = stage.get_children(); for (let i in children) { let actor = children[i]; actor.save_easing_state(); actor.set_easing_duration(300) actor.set_easing_mode(Clutter.AnimationMode.LINEAR); actor.scale_x = actor.scale_y = 0; actor.restore_easing_state(); let timeline = actor.get_transition('scale-x'); timeline.connect('completed', Lang.bind(this, function() { stage.remove_child(actor); })); break; } })); stage.show(); Clutter.main(); ---------------------------------------------------------------- And here is the backtrace : Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7ba35f8 in g_object_steal_qdata (object=object@entry=0x19e1180, quark=353) at gobject.c:3443 3443 g_return_val_if_fail (G_IS_OBJECT (object), NULL); (gdb) bt
+ Trace 232366
Actually it seems to be a Clutter problem.
Created attachment 251298 [details] C test case Adding a C version of the gjs script. Also leads to a crash.
Created attachment 251311 [details] [review] actor: unset remove-on-complete bit of a transition when removed from an actor
I think this is a bit of a roundabout way to go fixing the issue. we should just remove the set_remove_on_complete(TRUE) from _clutter_actor_create_transition(): all implicit transitions are removed when the ::stopped signal is emitted anyway, and then unreferenced, which will cause a ClutterTransition::detach() call. the detach() implementation will still operate on a valid pointer, because clutter_transition_set_animatable() will take a reference on the animatable instance. the issue is that ClutterTransition:remove-on-complete will automatically unref() the transition instance from within the signal emission, so it can be tricky to use with GC languages.
Created attachment 251803 [details] [review] actor: Do not set remove-on-complete on implicit transitions The implicitly created transitions are removed when complete by the implicit transition machinery. The remove-on-complete hint is for user-provided transitions.
with the commit above, the test does not crash any more (well, except the fact that the test adds a void timeout, so depending on the state of the stack the main loop may decide to run it again with an undefined actor).