After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 705739 - Crash when removing a ClutterActor from a scene at the end of an animation
Crash when removing a ClutterActor from a scene at the end of an animation
Status: RESOLVED FIXED
Product: clutter
Classification: Platform
Component: general
git master
Other Linux
: Normal normal
: ---
Assigned To: clutter-maint
clutter-maint
Depends on:
Blocks:
 
 
Reported: 2013-08-09 20:18 UTC by Lionel Landwerlin
Modified: 2013-08-19 23:25 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
C test case (1.29 KB, text/plain)
2013-08-11 16:44 UTC, Lionel Landwerlin
  Details
actor: unset remove-on-complete bit of a transition when removed from an actor (1.72 KB, patch)
2013-08-11 22:07 UTC, Lionel Landwerlin
none Details | Review
actor: Do not set remove-on-complete on implicit transitions (1.29 KB, patch)
2013-08-16 09:23 UTC, Emmanuele Bassi (:ebassi)
committed Details | Review

Description Lionel Landwerlin 2013-08-09 20:18:55 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
  • #0 g_object_steal_qdata
    at gobject.c line 3443
  • #1 clear_toggle_idle_source
    at gi/object.c line 800
  • #2 idle_handle_toggle
    at gi/object.c line 915
  • #3 g_main_dispatch
    at gmain.c line 3065
  • #4 g_main_context_dispatch
    at gmain.c line 3641
  • #5 g_main_context_iterate
    at gmain.c line 3712
  • #6 g_main_loop_run
    at gmain.c line 3906
  • #7 clutter_main
    at ./clutter-main.c line 980
  • #8 ffi_call_unix64
    from /usr/lib/x86_64-linux-gnu/libffi.so.6
  • #9 ffi_call
    from /usr/lib/x86_64-linux-gnu/libffi.so.6
  • #10 gjs_invoke_c_function
    at gi/function.c line 894
  • #11 function_call
    at gi/function.c line 1203
  • #12 CallJSNative
    at ./jscntxtinlines.h line 372
  • #13 js::InvokeKernel
    at /home/djdeath/src/jhbuild/trash/js17-17.0.0/js/src/jsinterp.cpp line 345
  • #14 js::Interpret
    at /home/djdeath/src/jhbuild/trash/js17-17.0.0/js/src/jsinterp.cpp line 2414
  • #15 js::RunScript
    at /home/djdeath/src/jhbuild/trash/js17-17.0.0/js/src/jsinterp.cpp line 309
  • #16 js::ExecuteKernel
    at /home/djdeath/src/jhbuild/trash/js17-17.0.0/js/src/jsinterp.cpp line 494
  • #17 js::Execute
    at /home/djdeath/src/jhbuild/trash/js17-17.0.0/js/src/jsinterp.cpp line 532
  • #18 JS::Evaluate
    at /home/djdeath/src/jhbuild/trash/js17-17.0.0/js/src/jsapi.cpp line 5670
  • #19 JS::Evaluate
  • #20 JS_EvaluateScript
  • #21 gjs_context_eval
    at gjs/context.c line 1020
  • #22 main
    at gjs/console.c line 122

Comment 1 Lionel Landwerlin 2013-08-11 16:43:17 UTC
Actually it seems to be a Clutter problem.
Comment 2 Lionel Landwerlin 2013-08-11 16:44:01 UTC
Created attachment 251298 [details]
C test case

Adding a C version of the gjs script.
Also leads to a crash.
Comment 3 Lionel Landwerlin 2013-08-11 22:07:47 UTC
Created attachment 251311 [details] [review]
actor: unset remove-on-complete bit of a transition when removed from an actor
Comment 4 Emmanuele Bassi (:ebassi) 2013-08-14 11:55:30 UTC
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.
Comment 5 Emmanuele Bassi (:ebassi) 2013-08-16 09:23:41 UTC
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.
Comment 6 Emmanuele Bassi (:ebassi) 2013-08-16 09:27:12 UTC
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).