Skip to content

  • Projects
  • Groups
  • Snippets
  • Help
  • This project
    • Loading...
  • Sign in / Register
gjs
gjs
  • Overview
    • Overview
    • Details
    • Activity
    • Cycle Analytics
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Charts
  • Issues 20
    • Issues 20
    • List
    • Board
    • Labels
    • Milestones
  • Merge Requests 2
    • Merge Requests 2
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
    • Charts
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Charts
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
  • GNOME
  • gjsgjs
  • Merge Requests
  • !22

Merged
Opened Nov 27, 2017 by Marco Trevisan@3v1n0 
  • Report abuse
Report abuse

object: check in gjs_typecheck_object if the object has been finalized

There are various crashes happening on gnome-shell because of gjs trying to act on invalid (destroyed) objects, so I guess it's saner to ensure that we're calling functions on an alive pointer

×

Check out, review, and merge locally

Step 1. Fetch and check out the branch for this merge request

git fetch https://gitlab.gnome.org/3v1n0/gjs.git gobject-ward
git checkout -b 3v1n0/gjs-gobject-ward FETCH_HEAD

Step 2. Review the changes locally

Step 3. Merge the branch and fix any conflicts that come up

git checkout master
git merge --no-ff 3v1n0/gjs-gobject-ward

Step 4. Push the result of the merge to GitLab

git push origin master

Note that pushing to GitLab requires write access to this repository.

Tip: You can also checkout merge requests locally by following these guidelines.

  • Discussion 31
  • Commits 5
  • Pipelines 12
  • Changes 3
{{ resolvedDiscussionCount }}/{{ discussionCount }} {{ resolvedCountText }} resolved
  • Marco Trevisan @3v1n0

    added 1 commit

    • c824a586 - object: don't resolve or set,get properties on finalized elements

    Compare with previous version

    Nov 27, 2017

    added 1 commit

    • c824a586 - object: don't resolve or set,get properties on finalized elements

    Compare with previous version

    added 1 commit * c824a586 - object: don't resolve or set,get properties on finalized elements [Compare with previous version](https://gitlab.gnome.org/GNOME/gjs/merge_requests/22/diffs?diff_id=500&start_sha=40084ad481771f85f0dd183d3e07c9d3ceefa4a6)
    Toggle commit list
  • Marco Trevisan @3v1n0

    added 1 commit

    • f94a9d07 - object: don't resolve or set,get properties on finalized elements

    Compare with previous version

    Nov 28, 2017

    added 1 commit

    • f94a9d07 - object: don't resolve or set,get properties on finalized elements

    Compare with previous version

    added 1 commit * f94a9d07 - object: don't resolve or set,get properties on finalized elements [Compare with previous version](https://gitlab.gnome.org/GNOME/gjs/merge_requests/22/diffs?diff_id=501&start_sha=c824a5863eb61fbc05805343ef8b935d44d871b7)
    Toggle commit list
  • Philip Chimento @ptomato commented Nov 28, 2017
    Master

    Thanks for the merge request. I read the background on the Bugzilla bug, to catch up a bit. On the one hand this Shouldn't Happen™ and I suspect the object is being destroyed on the C side where it shouldn't be. On the other hand we should definitely be robust to this.

    I get your point that it might affect performance, since we do have to do these checks in what are probably very hot paths. But I think it's worth it to be able to prevent crashes and print a helpful message that will lead to fixing faulty JS code faster. Until we actually have a good way to measure performance regressions it's just guesswork anyway.

    Thanks for the merge request. I read the background on the Bugzilla bug, to catch up a bit. On the one hand this Shouldn't Happen™ and I suspect the object is being destroyed on the C side where it shouldn't be. On the other hand we should definitely be robust to this. I get your point that it might affect performance, since we do have to do these checks in what are probably very hot paths. But I think it's worth it to be able to prevent crashes and print a helpful message that will lead to fixing faulty JS code faster. Until we actually have a good way to measure performance regressions it's just guesswork anyway.
  • Philip Chimento
    @ptomato started a discussion on an old version of the diff Nov 28, 2017
    Automatically resolved by Marco Trevisan with a push Nov 29, 2017
    gi/object.cpp
    390 391 if (priv->gobj == NULL) /* prototype, not an instance. */
    391 392 return true;
    392 393
    394 if (priv->g_object_finalized)
    395 return false;
    • Philip Chimento @ptomato commented Nov 28, 2017
      Master

      Returning false from a JSAPI function usually means an exception must be thrown. In this case, I would log a critical and return true. That will make the property get operation proceed on the JS side as if the object were a plain JS object.

      Alternatively, you could throw an exception on the JS side with gjs_throw(). But based on my hypothesis that this only happens when C code is behaving badly, my first instinct is to go for the transparent-to-JS approach.

      Edited Nov 28, 2017 by Philip Chimento
      Returning `false` from a JSAPI function usually means an exception must be thrown. In this case, I would log a critical and return `true`. That will make the property get operation proceed on the JS side as if the object were a plain JS object. Alternatively, you could throw an exception on the JS side with `gjs_throw()`. But based on my hypothesis that this only happens when C code is behaving badly, my first instinct is to go for the transparent-to-JS approach.
    • Marco Trevisan @3v1n0 commented Nov 29, 2017
      Developer

      I've tried using g_critical only for this, but the problem of it is that it's not causing any JS stack to be shown, while I'd prefer to see it.

      So I guess returning true and gjs_throw is fine anyway, as it seems to do both things requested.

      I've tried using `g_critical` only for this, but the problem of it is that it's not causing any JS stack to be shown, while I'd prefer to see it. So I guess returning `true` and `gjs_throw` is fine anyway, as it seems to do both things requested.
    • Philip Chimento @ptomato commented Nov 29, 2017
      Master

      You can also print a JS stack with gjs_dumpstack().

      You can also print a JS stack with `gjs_dumpstack()`.
    • Marco Trevisan @3v1n0 commented Nov 29, 2017
      Developer

      Yep, I new it... Not sure what was the preferred way here... g_critical + dumpstack or just a gjs_throw?

      Yep, I new it... Not sure what was the preferred way here... g_critical + dumpstack or just a gjs_throw?
    • Marco Trevisan @3v1n0

      changed this line in version 4 of the diff

      Nov 29, 2017

      changed this line in version 4 of the diff

      changed this line in [version 4 of the diff](https://gitlab.gnome.org/GNOME/gjs/merge_requests/22/diffs?diff_id=522&start_sha=f94a9d07c70004438b5edcf7e5c7ead195ddebfb#fd9d2d7a82fce609fc319a328f60bf4ee4bc26df_395_394)
      Toggle commit list
    Please register or sign in to reply
  • Philip Chimento
    @ptomato started a discussion on an old version of the diff Nov 28, 2017
    Resolved by Marco Trevisan Nov 29, 2017
    gi/object.cpp
    500 504 if (priv->gobj == NULL) /* prototype, not an instance. */
    501 505 return result.succeed();
    502 506
    507 if (priv->g_object_finalized)
    508 return false;
    • Philip Chimento @ptomato commented Nov 28, 2017
      Master

      Same here, I would log a critical and return result.succeed().

      Same here, I would log a critical and `return result.succeed()`.
    • Marco Trevisan @3v1n0

      changed this line in version 4 of the diff

      Nov 29, 2017

      changed this line in version 4 of the diff

      changed this line in [version 4 of the diff](https://gitlab.gnome.org/GNOME/gjs/merge_requests/22/diffs?diff_id=522&start_sha=f94a9d07c70004438b5edcf7e5c7ead195ddebfb#fd9d2d7a82fce609fc319a328f60bf4ee4bc26df_508_513)
      Toggle commit list
    Please register or sign in to reply
  • Philip Chimento
    @ptomato started a discussion on an old version of the diff Nov 28, 2017
    Automatically resolved by Marco Trevisan with a push Nov 29, 2017
    gi/object.cpp
    737 744 return true;
    738 745 }
    739 746
    747 if (priv->g_object_finalized) {
    748 *resolved = false;
    749 return false;
    • Philip Chimento @ptomato commented Nov 28, 2017
      Master

      Same here.

      Same here.
    • Marco Trevisan @3v1n0 commented Nov 29, 2017
      Developer

      Returning true here too?

      Returning true here too?
    • Philip Chimento @ptomato commented Nov 29, 2017
      Master

      Yes, returning false here also means an exception must be thrown.

      Yes, returning false here also means an exception must be thrown.
    • Marco Trevisan @3v1n0

      changed this line in version 4 of the diff

      Nov 29, 2017

      changed this line in version 4 of the diff

      changed this line in [version 4 of the diff](https://gitlab.gnome.org/GNOME/gjs/merge_requests/22/diffs?diff_id=522&start_sha=f94a9d07c70004438b5edcf7e5c7ead195ddebfb#fd9d2d7a82fce609fc319a328f60bf4ee4bc26df_749_761)
      Toggle commit list
    Please register or sign in to reply
  • Philip Chimento
    @ptomato started a discussion on an old version of the diff Nov 28, 2017
    Automatically resolved by Marco Trevisan with a push Nov 29, 2017
    gi/object.cpp
    920 932 wrapped_gobj_dispose_notify(gpointer data,
    921 933 GObject *where_the_object_was)
    922 934 {
    923 wrapped_gobject_list.erase(static_cast<ObjectInstance *>(data));
    935 ObjectInstance *priv = static_cast<ObjectInstance *>(data);
    • Philip Chimento @ptomato commented Nov 28, 2017
      Master

      nitpick style rule that I haven't written down yet: in new code I prefer using auto if the variable's type is already clearly stated in a static_cast<> operator.

      nitpick style rule that I haven't written down yet: in new code I prefer using `auto` if the variable's type is already clearly stated in a `static_cast<>` operator.
    • Marco Trevisan @3v1n0 commented Nov 29, 2017
      Developer

      Seeing my C++1x backgroound (and love for it), I wanted to do it, but I noticed that auto wasn't much used yet... So I went classic. Happy to update it.

      Seeing my C++1x backgroound (and love for it), I wanted to do it, but I noticed that `auto` wasn't much used yet... So I went classic. Happy to update it.
    • Marco Trevisan @3v1n0

      changed this line in version 4 of the diff

      Nov 29, 2017

      changed this line in version 4 of the diff

      changed this line in [version 4 of the diff](https://gitlab.gnome.org/GNOME/gjs/merge_requests/22/diffs?diff_id=522&start_sha=f94a9d07c70004438b5edcf7e5c7ead195ddebfb#fd9d2d7a82fce609fc319a328f60bf4ee4bc26df_935_952)
      Toggle commit list
    Please register or sign in to reply
  • Philip Chimento
    @ptomato started a discussion on an old version of the diff Nov 28, 2017
    Resolved by Marco Trevisan Nov 29, 2017
    gi/object.cpp
    1418 1433 ObjectInstance *priv;
    1419 1434
    1420 1435 priv = (ObjectInstance *) JS_GetPrivate(obj);
    1421 if (priv == NULL)
    1436 if (priv == NULL || priv->g_object_finalized)
    • Philip Chimento @ptomato commented Nov 28, 2017
      Master

      I would make this a separate condition and log a critical here too.

      I would make this a separate condition and log a critical here too.
    • Marco Trevisan @3v1n0

      changed this line in version 4 of the diff

      Nov 29, 2017

      changed this line in version 4 of the diff

      changed this line in [version 4 of the diff](https://gitlab.gnome.org/GNOME/gjs/merge_requests/22/diffs?diff_id=522&start_sha=f94a9d07c70004438b5edcf7e5c7ead195ddebfb#fd9d2d7a82fce609fc319a328f60bf4ee4bc26df_1436_1453)
      Toggle commit list
    Please register or sign in to reply
  • Philip Chimento
    @ptomato started a discussion on an old version of the diff Nov 28, 2017
    Resolved by Philip Chimento Nov 30, 2017
    gi/object.cpp
    2115 2130 return false;
    2116 2131 }
    2117 2132
    2133 if (priv->g_object_finalized) {
    2134 if (throw_error) {
    • Philip Chimento @ptomato commented Nov 28, 2017
      Master

      We should consider what to do if throw_error is false - should we log a critical there too? Or possibly log a critical in both cases.

      Edited Nov 28, 2017 by Philip Chimento
      We should consider what to do if `throw_error` is `false` - should we log a critical there too? Or possibly log a critical in both cases.
    • Marco Trevisan @3v1n0 commented Nov 29, 2017
      Developer

      Mh, yeah, I guess throwing should happen in any case here... Or just showing a critical otherwise.

      Mh, yeah, I guess throwing should happen in any case here... Or just showing a critical otherwise.
    • Marco Trevisan @3v1n0

      changed this line in version 10 of the diff

      Dec 01, 2017

      changed this line in version 10 of the diff

      changed this line in [version 10 of the diff](https://gitlab.gnome.org/GNOME/gjs/merge_requests/22/diffs?diff_id=552&start_sha=d7cfbcdc142f4e1b8cdd31d46a38694e1b2c02b7#fd9d2d7a82fce609fc319a328f60bf4ee4bc26df_2164_2164)
      Toggle commit list
    Please register or sign in to reply
  • Philip Chimento
    @ptomato started a discussion on an old version of the diff Nov 28, 2017
    Automatically resolved by Marco Trevisan with a push Nov 29, 2017
    gi/object.cpp
    2115 2130 return false;
    2116 2131 }
    2117 2132
    2133 if (priv->g_object_finalized) {
    2134 if (throw_error) {
    2135 gjs_throw(context,
    2136 "Object is %s.%s.prototype, has been already deallocated - cannot convert to GObject*",
    • Philip Chimento @ptomato commented Nov 28, 2017
      Master

      This message isn't quite accurate, the object isn't %s.%s.prototype. In that case priv->gobj would have been nullptr.

      In any case I would suggest making a more verbose error message that will help shell extension authors track down what they might be doing wrong. Here's an example of such a message from elsewhere in GJS.

      This message isn't quite accurate, the object isn't `%s.%s.prototype`. In that case `priv->gobj` would have been `nullptr`. In any case I would suggest making a more verbose error message that will help shell extension authors track down what they might be doing wrong. [Here](https://gitlab.gnome.org/GNOME/gjs/blob/master/gi/value.cpp#L143-148)'s an example of such a message from elsewhere in GJS.
    • Marco Trevisan @3v1n0

      changed this line in version 4 of the diff

      Nov 29, 2017

      changed this line in version 4 of the diff

      changed this line in [version 4 of the diff](https://gitlab.gnome.org/GNOME/gjs/merge_requests/22/diffs?diff_id=522&start_sha=f94a9d07c70004438b5edcf7e5c7ead195ddebfb#fd9d2d7a82fce609fc319a328f60bf4ee4bc26df_2136_2162)
      Toggle commit list
    Please register or sign in to reply
  • Philip Chimento @ptomato commented Nov 28, 2017
    Master

    I have a few other ideas for improvements. I think that if you do priv->keep_alive.reset() when a finalized GObject is detected, that should at least release the GC root that the GObject keeps on the JS object, making it more likely to be garbage collected next time around.

    It would also be nice to have a regression test for this situation. The code in object.cpp is pretty complicated, so I'd like to be sure that when it's changed, we're not going back to making shell extension code crash. A good place for this test might be gjs/test/gjs-tests.cpp unless you know of a way to trigger the bug purely in JS code.

    I have a few other ideas for improvements. I _think_ that if you do `priv->keep_alive.reset()` when a finalized GObject is detected, that should at least release the GC root that the GObject keeps on the JS object, making it more likely to be garbage collected next time around. It would also be nice to have a regression test for this situation. The code in `object.cpp` is pretty complicated, so I'd like to be sure that when it's changed, we're not going back to making shell extension code crash. A good place for this test might be `gjs/test/gjs-tests.cpp` unless you know of a way to trigger the bug purely in JS code.
  • Marco Trevisan @3v1n0

    added 1 commit

    • 6748006d - object: add better logging when invalid access happens, also don't block it

    Compare with previous version

    Nov 29, 2017

    added 1 commit

    • 6748006d - object: add better logging when invalid access happens, also don't block it

    Compare with previous version

    added 1 commit * 6748006d - object: add better logging when invalid access happens, also don&#x27;t block it [Compare with previous version](https://gitlab.gnome.org/GNOME/gjs/merge_requests/22/diffs?diff_id=522&start_sha=f94a9d07c70004438b5edcf7e5c7ead195ddebfb)
    Toggle commit list
  • Marco Trevisan @3v1n0

    added 1 commit

    • 73eb5486 - object: reset the keep alive flag on wrapper when object is disposed

    Compare with previous version

    Nov 29, 2017

    added 1 commit

    • 73eb5486 - object: reset the keep alive flag on wrapper when object is disposed

    Compare with previous version

    added 1 commit * 73eb5486 - object: reset the keep alive flag on wrapper when object is disposed [Compare with previous version](https://gitlab.gnome.org/GNOME/gjs/merge_requests/22/diffs?diff_id=523&start_sha=6748006d0ab6850b80a0014e9f1e31f7aca722bb)
    Toggle commit list
  • Marco Trevisan @3v1n0 commented Nov 29, 2017
    Developer

    Ok, I've updated the PR with some more commits doing what you required... I know I'm terrible when it comes to logging and being explicative, so please feel free to suggest better wording if you want.

    have a few other ideas for improvements. I think that if you do priv->keep_alive.reset() when a finalized GObject is detected, that should at least release the GC root that the GObject keeps on the JS object, making it more likely to be garbage collected next time around.

    Good idea, I've added that.

    It would also be nice to have a regression test for this situation. The code in object.cpp is pretty complicated, so I'd like to be sure that when it's changed, we're not going back to making shell extension code crash.

    Ok, let me look into this.

    unless you know of a way to trigger the bug purely in JS code.

    While I had some hacks to get that happening in G-S it's really not the best way, while for example a code like this below, triggers things

    imports.gi.versions.Gtk = "3.0";
    
    const GLib = imports.gi.GLib;
    const Gtk = imports.gi.Gtk;
    
    Gtk.init(null);
    
    let loop = GLib.MainLoop.new(null, false);
    let win = new Gtk.Window({type: Gtk.WindowType.TOPLEVEL})
    
    GLib.timeout_add(GLib.PRIORITY_DEFAULT, 500, function() {
      print(win);
      print(win.title);
      //win.set_title("foo");
      win.title = "foo";
      loop.quit();
      return false;
    })
    
    win.destroy();
    
    loop.run();

    Or just without any timeout:

    imports.gi.versions.Gtk = "3.0";
    
    const GLib = imports.gi.GLib;
    const Gtk = imports.gi.Gtk;
    
    Gtk.init(null);
    
    let win = new Gtk.Window({type: Gtk.WindowType.TOPLEVEL})
    win.destroy()
    
    print(win);
    print(win.title);
    win.title = "foo";
    win.set_title("foo");
    Edited Nov 29, 2017 by Marco Trevisan
    Ok, I've updated the PR with some more commits doing what you required... I know I'm terrible when it comes to logging and being explicative, so please feel free to suggest better wording if you want. > have a few other ideas for improvements. I think that if you do priv->keep_alive.reset() when a finalized GObject is detected, that should at least release the GC root that the GObject keeps on the JS object, making it more likely to be garbage collected next time around. Good idea, I've added that. > It would also be nice to have a regression test for this situation. The code in `object.cpp` is pretty complicated, so I'd like to be sure that when it's changed, we're not going back to making shell extension code crash. Ok, let me look into this. > unless you know of a way to trigger the bug purely in JS code. While I had some hacks to get that happening in G-S it's really not the best way, while for example a code like this below, triggers things ```javascript imports.gi.versions.Gtk = "3.0"; const GLib = imports.gi.GLib; const Gtk = imports.gi.Gtk; Gtk.init(null); let loop = GLib.MainLoop.new(null, false); let win = new Gtk.Window({type: Gtk.WindowType.TOPLEVEL}) GLib.timeout_add(GLib.PRIORITY_DEFAULT, 500, function() { print(win); print(win.title); //win.set_title("foo"); win.title = "foo"; loop.quit(); return false; }) win.destroy(); loop.run(); ``` Or just without any timeout: ```javascript imports.gi.versions.Gtk = "3.0"; const GLib = imports.gi.GLib; const Gtk = imports.gi.Gtk; Gtk.init(null); let win = new Gtk.Window({type: Gtk.WindowType.TOPLEVEL}) win.destroy() print(win); print(win.title); win.title = "foo"; win.set_title("foo"); ```
  • Marco Trevisan @3v1n0

    added 2 commits

    • b64b5b45 - object: add better logging when invalid access happens, also don't block it
    • a1d07c79 - object: reset the keep alive flag on wrapper when object is disposed

    Compare with previous version

    Nov 29, 2017

    added 2 commits

    • b64b5b45 - object: add better logging when invalid access happens, also don't block it
    • a1d07c79 - object: reset the keep alive flag on wrapper when object is disposed

    Compare with previous version

    added 2 commits * b64b5b45 - object: add better logging when invalid access happens, also don&#x27;t block it * a1d07c79 - object: reset the keep alive flag on wrapper when object is disposed [Compare with previous version](https://gitlab.gnome.org/GNOME/gjs/merge_requests/22/diffs?diff_id=527&start_sha=73eb54861d5c9bddee13e92ba93e821814254a21)
    Toggle commit list
  • Philip Chimento @ptomato

    resolved all discussions

    Nov 30, 2017

    resolved all discussions

    resolved all discussions
    Toggle commit list
  • Philip Chimento
    @ptomato started a discussion on an old version of the diff Nov 30, 2017
    Resolved by Marco Trevisan Dec 01, 2017
    gi/object.cpp
    390 391 if (priv->gobj == NULL) /* prototype, not an instance. */
    391 392 return true;
    392 393
    394 if (priv->g_object_finalized) {
    395 g_critical("Object %s.%s (%p), has been already finalized. "
    396 "Impossible to get any property from it.",
    397 priv->info ? g_base_info_get_namespace( (GIBaseInfo*) priv->info) : "",
    • Philip Chimento @ptomato commented Nov 30, 2017
      Master

      For future reference I try to use static_cast<> in new code instead of C casts, but I have a branch where I'm refactoring existing uses of this anyway, so no need to bother - I'll fix it up when I rebase.

      For future reference I try to use `static_cast<>` in new code instead of C casts, but I have a branch where I'm refactoring existing uses of this anyway, so no need to bother - I'll fix it up when I rebase.
    • Marco Trevisan @3v1n0 commented Nov 30, 2017
      Developer

      I actually wanted to do it, but since it wans't used everywhere I wasn't aware of the policy.

      I actually wanted to do it, but since it wans't used everywhere I wasn't aware of the policy.
    • Marco Trevisan @3v1n0

      changed this line in version 10 of the diff

      Dec 01, 2017

      changed this line in version 10 of the diff

      changed this line in [version 10 of the diff](https://gitlab.gnome.org/GNOME/gjs/merge_requests/22/diffs?diff_id=552&start_sha=d7cfbcdc142f4e1b8cdd31d46a38694e1b2c02b7#fd9d2d7a82fce609fc319a328f60bf4ee4bc26df_397_395)
      Toggle commit list
    Please register or sign in to reply
  • Philip Chimento @ptomato

    resolved all discussions

    Nov 30, 2017

    resolved all discussions

    resolved all discussions
    Toggle commit list
  • Philip Chimento
    @ptomato started a discussion on the diff Nov 30, 2017
    Resolved by Philip Chimento Nov 30, 2017
    gi/object.cpp
    920 952 wrapped_gobj_dispose_notify(gpointer data,
    921 953 GObject *where_the_object_was)
    922 954 {
    923 wrapped_gobject_list.erase(static_cast<ObjectInstance *>(data));
    955 auto *priv = static_cast<ObjectInstance *>(data);
    • Philip Chimento @ptomato commented Nov 30, 2017
      Master

      I wasn't aware of auto *, I thought the pointer was already absorbed into auto! Should I start doing this too, to write more idiomatic C++ style?

      I wasn't aware of `auto *`, I thought the pointer was already absorbed into `auto`! Should I start doing this too, to write more idiomatic C++ style?
    • Marco Trevisan @3v1n0 commented Nov 30, 2017
      Developer

      You can use also auto& when needed to ensure it's a ref.

      Here I think it's better when you're sure it's a pointer and you still want to make it clear, while it won't change the result, it will keep things easier to read IMHO.

      You can use also auto& when needed to ensure it's a ref. Here I think it's better when you're sure it's a pointer and you still want to make it clear, while it won't change the result, it will keep things easier to read IMHO.
    Please register or sign in to reply
  • Philip Chimento @ptomato commented Nov 30, 2017
    Master

    Looks good now, let me know if you need any help with the test.

    I did try the two JS snippets you posted, but they didn't crash for me. However, they did print the log messages when building with your branch, so I guess I was just lucky. I think the latter one is a good one to base the test on.

    PS. If you have a C++1x background then can I ask for your help on some future reviews? 😄 I am not the most experienced in C++, I kind of picked it up when I took over maintainership of GJS.

    Looks good now, let me know if you need any help with the test. I did try the two JS snippets you posted, but they didn't crash for me. However, they did print the log messages when building with your branch, so I guess I was just lucky. I think the latter one is a good one to base the test on. PS. If you have a C++1x background then can I ask for your help on some future reviews? :smile: I am not the most experienced in C++, I kind of picked it up when I took over maintainership of GJS.
  • Marco Trevisan @3v1n0 commented Nov 30, 2017
    Developer

    As for the test I'm not sure how to proceed...

    Also, probably (by running G-S whith this) I was thinking that maybe it would be better to to use a lower priority message in object_instance_trace, as it looks to lead to be very verbose, while the dumpstack doesn't seem to be often available.

    As for the test I'm not sure how to proceed... Also, probably (by running G-S whith this) I was thinking that maybe it would be better to to use a lower priority message in object_instance_trace, as it looks to lead to be very verbose, while the dumpstack doesn't seem to be often available.
  • Marco Trevisan @3v1n0 commented Nov 30, 2017
    Developer

    PS. If you have a C++1x background then can I ask for your help on some future reviews? 😄 I am not the most experienced in C++, I kind of picked it up when I took over maintainership of GJS.

    Sure, feel free! I've done quite a lot of lines of it...

    > PS. If you have a C++1x background then can I ask for your help on some future reviews? :smile: I am not the most experienced in C++, I kind of picked it up when I took over maintainership of GJS. Sure, feel free! I've done [quite a lot of lines](https://www.openhub.net/accounts/Trevinho/languages) of it...
  • Philip Chimento @ptomato commented Nov 30, 2017
    Master

    As for the test I'm not sure how to proceed...

    I'd suggest adding it to one of the files in installed-tests/js/. There's a "Garbage collection of introspected objects" section at the end of testEverythingEncapsulated.js which seems like a good place. We use Jasmine 2.5 for unit testing which you can read about here. To test that the messages are logged, you can use GLib.test_expect_message() and GLib.test_assert_expected_messages_internal(), there's an example of how to do that in testExceptions.js.

    Also, probably (by running G-S whith this) I was thinking that maybe it would be better to to use a lower priority message in object_instance_trace, as it looks to lead to be very verbose, while the dumpstack doesn't seem to be often available.

    That's a good point, I didn't think about it. Tracing will indeed take place many times during garbage collection, and that's exactly when the JS stack isn't so important. So probably a good idea to just silently exit from trace.

    > As for the test I'm not sure how to proceed... I'd suggest adding it to one of the files in `installed-tests/js/`. There's a "Garbage collection of introspected objects" section at the end of `testEverythingEncapsulated.js` which seems like a good place. We use Jasmine 2.5 for unit testing which you can read about [here](https://jasmine.github.io/2.5/introduction). To test that the messages are logged, you can use `GLib.test_expect_message()` and `GLib.test_assert_expected_messages_internal()`, there's an example of how to do that in `testExceptions.js`. > Also, probably (by running G-S whith this) I was thinking that maybe it would be better to to use a lower priority message in object_instance_trace, as it looks to lead to be very verbose, while the dumpstack doesn't seem to be often available. That's a good point, I didn't think about it. Tracing will indeed take place many times during garbage collection, and that's exactly when the JS stack isn't so important. So probably a good idea to just silently exit from trace.
  • Marco Trevisan @3v1n0

    added 2 commits

    • 1907067e - object: add better logging when invalid access happens, also don't block it
    • 126f6f5e - object: reset the keep alive flag on wrapper when object is disposed

    Compare with previous version

    Nov 30, 2017

    added 2 commits

    • 1907067e - object: add better logging when invalid access happens, also don't block it
    • 126f6f5e - object: reset the keep alive flag on wrapper when object is disposed

    Compare with previous version

    added 2 commits * 1907067e - object: add better logging when invalid access happens, also don&#x27;t block it * 126f6f5e - object: reset the keep alive flag on wrapper when object is disposed [Compare with previous version](https://gitlab.gnome.org/GNOME/gjs/merge_requests/22/diffs?diff_id=539&start_sha=a1d07c7902198d46383d0f5ad6b6d5ed7c15c0c8)
    Toggle commit list
  • Marco Trevisan @3v1n0

    added 3 commits

    • 95928e8e - object: add better logging when invalid access happens, also don't block it
    • bf39334f - object: reset the keep alive flag on wrapper when object is disposed
    • e35ccd24 - installed-tests/js: add testGObjectDestructionAccess to verify access to destryed objects

    Compare with previous version

    Nov 30, 2017

    added 3 commits

    • 95928e8e - object: add better logging when invalid access happens, also don't block it
    • bf39334f - object: reset the keep alive flag on wrapper when object is disposed
    • e35ccd24 - installed-tests/js: add testGObjectDestructionAccess to verify access to destryed objects

    Compare with previous version

    added 3 commits * 95928e8e - object: add better logging when invalid access happens, also don&#x27;t block it * bf39334f - object: reset the keep alive flag on wrapper when object is disposed * e35ccd24 - installed-tests&#x2F;js: add testGObjectDestructionAccess to verify access to destryed objects [Compare with previous version](https://gitlab.gnome.org/GNOME/gjs/merge_requests/22/diffs?diff_id=540&start_sha=126f6f5edf4d70c4c324c837906447178da66ec4)
    Toggle commit list
  • Marco Trevisan @3v1n0

    added 1 commit

    • d7cfbcdc - installed-tests/js: add testGObjectDestructionAccess to verify access to destryed objects

    Compare with previous version

    Dec 01, 2017

    added 1 commit

    • d7cfbcdc - installed-tests/js: add testGObjectDestructionAccess to verify access to destryed objects

    Compare with previous version

    added 1 commit * d7cfbcdc - installed-tests&#x2F;js: add testGObjectDestructionAccess to verify access to destryed objects [Compare with previous version](https://gitlab.gnome.org/GNOME/gjs/merge_requests/22/diffs?diff_id=541&start_sha=e35ccd24995fb0fdf5e1fb65c0e6d1ff8fd8b03f)
    Toggle commit list
  • Marco Trevisan @3v1n0

    resolved all discussions

    Dec 01, 2017

    resolved all discussions

    resolved all discussions
    Toggle commit list
  • Philip Chimento
    @ptomato started a discussion on the diff Dec 01, 2017
    Resolved by Marco Trevisan Dec 01, 2017
    installed-tests/js/testGObjectDestructionAccess.js 0 → 100644
    27 });
    28
    29 it('Set property', () => {
    30 GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_CRITICAL,
    31 'Object Gtk.Window*');
    32
    33 destroyedWindow.title = 'I am dead';
    34
    35 GLib.test_assert_expected_messages_internal('Gjs', 'testGObjectDestructionAccess.js', 0,
    36 'testExceptionInDestroyedObjectPropertySet');
    37 });
    38
    39 it('Access to getter method', () => {
    40 expect(() => {
    41 let title = destroyedWindow.get_title();
    42 }).toThrowError(/Object Gtk.Window \(0x[a-f0-9]+\), has been already deallocated.*/)
    • Philip Chimento @ptomato commented Dec 01, 2017
      Master

      Heh, it was good you wrote this test — I realize now that the implementation is kind of inconsistent, because calling a method through GObject-introspection will call gjs_typecheck_object() which will throw, even if the other faulty accesses just log.

      I suppose we should pick either logging or throwing, and make it do only one. If we pick logging, then I guess gjs_typecheck_object() should not throw even if throw_error is requested. In a way that makes sense, the object was of the correct type, it's just gone 😄 If we pick throwing, then every operation should just throw (except tracing.)

      Heh, it was good you wrote this test — I realize now that the implementation is kind of inconsistent, because calling a method through GObject-introspection will call `gjs_typecheck_object()` which will throw, even if the other faulty accesses just log. I suppose we should pick either logging or throwing, and make it do only one. If we pick logging, then I guess `gjs_typecheck_object()` should not throw even if `throw_error` is requested. In a way that makes sense, the object was of the correct type, it's just gone :smile: If we pick throwing, then every operation should just throw (except tracing.)
    • Marco Trevisan @3v1n0 commented Dec 01, 2017
      Developer

      As you wish, for me both ways are the same... Throwing is probably cleaner for some aspects (as it also dumps the stack), but it might have other side effects I'm not fully aware of.

      So up to you... Just tell me the strategy you prefer, and I'll follow that. ;-)

      As you wish, for me both ways are the same... Throwing is probably cleaner for some aspects (as it also dumps the stack), but it might have other side effects I'm not fully aware of. So up to you... Just tell me the strategy you prefer, and I'll follow that. ;-)
    • Philip Chimento @ptomato commented Dec 01, 2017
      Master

      I was originally leaning toward logging, but I've come to think throwing is better. It makes the error harder to ignore, so app and shell extension authors will be less likely to publish buggy JS code, and if the fault is not in their code then they will be more likely to report a gnome-shell bug to get it fixed. Also, execution can't meaningfully continue anyway when our invariant of JS objects wrapping only live GObjects is broken.

      So, to throw, then all the operations should call gjs_throw(), not touch any output params, and return false.

      I was originally leaning toward logging, but I've come to think throwing is better. It makes the error harder to ignore, so app and shell extension authors will be less likely to publish buggy JS code, and if the fault is not in their code then they will be more likely to report a gnome-shell bug to get it fixed. Also, execution can't meaningfully continue anyway when our invariant of JS objects wrapping only live GObjects is broken. So, to throw, then all the operations should call `gjs_throw()`, not touch any output params, and return false.
    Please register or sign in to reply
  • Marco Trevisan @3v1n0

    resolved all discussions

    Dec 01, 2017

    resolved all discussions

    resolved all discussions
    Toggle commit list
  • Marco Trevisan @3v1n0

    resolved all discussions

    Dec 01, 2017

    resolved all discussions

    resolved all discussions
    Toggle commit list
  • Marco Trevisan @3v1n0

    added 3 commits

    • b4cae4b3 - object: add better logging when invalid access happens
    • 81225d06 - object: reset the keep alive flag on wrapper when object is disposed
    • 516012f8 - installed-tests/js: add testGObjectDestructionAccess to verify access to destryed objects

    Compare with previous version

    Dec 01, 2017

    added 3 commits

    • b4cae4b3 - object: add better logging when invalid access happens
    • 81225d06 - object: reset the keep alive flag on wrapper when object is disposed
    • 516012f8 - installed-tests/js: add testGObjectDestructionAccess to verify access to destryed objects

    Compare with previous version

    added 3 commits * b4cae4b3 - object: add better logging when invalid access happens * 81225d06 - object: reset the keep alive flag on wrapper when object is disposed * 516012f8 - installed-tests&#x2F;js: add testGObjectDestructionAccess to verify access to destryed objects [Compare with previous version](https://gitlab.gnome.org/GNOME/gjs/merge_requests/22/diffs?diff_id=552&start_sha=d7cfbcdc142f4e1b8cdd31d46a38694e1b2c02b7)
    Toggle commit list
  • Marco Trevisan @3v1n0

    resolved all discussions

    Dec 01, 2017

    resolved all discussions

    resolved all discussions
    Toggle commit list
  • Marco Trevisan @3v1n0

    added 1 commit

    • c7293959 - installed-tests/js: add testGObjectDestructionAccess to verify access to destryed objects

    Compare with previous version

    Dec 01, 2017

    added 1 commit

    • c7293959 - installed-tests/js: add testGObjectDestructionAccess to verify access to destryed objects

    Compare with previous version

    added 1 commit * c7293959 - installed-tests&#x2F;js: add testGObjectDestructionAccess to verify access to destryed objects [Compare with previous version](https://gitlab.gnome.org/GNOME/gjs/merge_requests/22/diffs?diff_id=553&start_sha=516012f8254a2542126c0ac36bc7d39a46f74d49)
    Toggle commit list
  • Marco Trevisan @3v1n0

    resolved all discussions

    Dec 01, 2017

    resolved all discussions

    resolved all discussions
    Toggle commit list
  • Marco Trevisan @3v1n0

    added 1 commit

    • 6be9eb13 - installed-tests/js: add testGObjectDestructionAccess to verify access to destryed objects

    Compare with previous version

    Dec 01, 2017

    added 1 commit

    • 6be9eb13 - installed-tests/js: add testGObjectDestructionAccess to verify access to destryed objects

    Compare with previous version

    added 1 commit * 6be9eb13 - installed-tests&#x2F;js: add testGObjectDestructionAccess to verify access to destryed objects [Compare with previous version](https://gitlab.gnome.org/GNOME/gjs/merge_requests/22/diffs?diff_id=554&start_sha=c7293959a57d163438998bce66697f92334c90ad)
    Toggle commit list
  • Marco Trevisan @3v1n0 commented Dec 01, 2017
    Developer

    Updated as requested, I think it should good to go now :)

    Updated as requested, I think it should good to go now :)
  • Philip Chimento
    @ptomato started a discussion on the diff Dec 01, 2017
    Resolved by Philip Chimento Dec 01, 2017
    gi/object.cpp
    737 757 return true;
    738 758 }
    739 759
    760 if (priv->g_object_finalized) {
    761 *resolved = false;
    • Philip Chimento @ptomato commented Dec 01, 2017
      Master

      Technically according to the SpiderMonkey API you are supposed to leave this out parameter unchanged if you return false. I don't think it makes a difference in practice, but I'll make a quick followup commit to remove this line.

      Technically according to the SpiderMonkey API you are supposed to leave this out parameter unchanged if you return false. I don't think it makes a difference in practice, but I'll make a quick followup commit to remove this line.
    Please register or sign in to reply
  • Philip Chimento @ptomato

    resolved all discussions

    Dec 01, 2017

    resolved all discussions

    resolved all discussions
    Toggle commit list
  • Philip Chimento @ptomato

    mentioned in commit db3a7832

    Dec 01, 2017

    mentioned in commit db3a7832

    mentioned in commit db3a78326fe4dfc2fb7bdeeebee40f33043abd21
    Toggle commit list
  • Philip Chimento @ptomato

    merged

    Dec 01, 2017

    merged

    merged
    Toggle commit list
  • Philip Chimento @ptomato commented Dec 01, 2017
    Master

    Thanks for all the work! 🎉

    Thanks for all the work! :tada:
  • Philip Chimento @ptomato

    mentioned in commit 7a997610

    Dec 01, 2017

    mentioned in commit 7a997610

    mentioned in commit 7a9976100152e471729efefa81763ab283ff6320
    Toggle commit list
  • Marco Trevisan @3v1n0

    mentioned in merge request !25 (merged)

    Dec 05, 2017

    mentioned in merge request !25 (merged)

    mentioned in merge request !25
    Toggle commit list
  • Marco Trevisan @3v1n0

    mentioned in merge request !27 (merged)

    Dec 06, 2017

    mentioned in merge request !27 (merged)

    mentioned in merge request !27
    Toggle commit list
  • Max Bruckner
    @FSMaxB started a discussion on commit 40084ad4 Dec 08, 2017
    • Max Bruckner @FSMaxB

      mentioned in issue #21 (closed)

      Dec 08, 2017

      mentioned in issue #21 (closed)

      mentioned in issue #21
      Toggle commit list
    Please register or sign in to reply
  • Marco Trevisan
    @3v1n0 started a discussion on commit 81225d06 Dec 11, 2017
    • Marco Trevisan @3v1n0

      mentioned in issue #23 (closed)

      Dec 11, 2017

      mentioned in issue #23 (closed)

      mentioned in issue #23
      Toggle commit list
    Please register or sign in to reply
  • Write
  • Preview
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment
Assignee
No assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking
0
Labels
None
Assign labels
  • View labels
Reference: GNOME/gjs!22
×

Revert this merge request

Switch branch
Cancel
A new branch will be created in your fork and a new merge request will be started.
×

Cherry-pick this merge request

Switch branch
Cancel
A new branch will be created in your fork and a new merge request will be started.