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
-
added 1 commit
- c824a586 - object: don't resolve or set,get properties on finalized elements
Toggle commit list -
added 1 commit
- f94a9d07 - object: don't resolve or set,get properties on finalized elements
Toggle commit list -
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.
-
-
-
-
-
-
-
-
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.cppis 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 begjs/test/gjs-tests.cppunless you know of a way to trigger the bug purely in JS code. -
added 1 commit
- 6748006d - object: add better logging when invalid access happens, also don't block it
Toggle commit list -
added 1 commit
- 73eb5486 - object: reset the keep alive flag on wrapper when object is disposed
Toggle commit list -
DeveloperEdited 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.cppis 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"); -
resolved all discussions
Toggle commit list -
-
resolved all discussions
Toggle commit list -
-
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. -
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.
-
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...
-
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 oftestEverythingEncapsulated.jswhich 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 useGLib.test_expect_message()andGLib.test_assert_expected_messages_internal(), there's an example of how to do that intestExceptions.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.
-
added 3 commits
Toggle commit list -
added 1 commit
- d7cfbcdc - installed-tests/js: add testGObjectDestructionAccess to verify access to destryed objects
Toggle commit list -
resolved all discussions
Toggle commit list -
-
resolved all discussions
Toggle commit list -
resolved all discussions
Toggle commit list -
resolved all discussions
Toggle commit list -
added 1 commit
- c7293959 - installed-tests/js: add testGObjectDestructionAccess to verify access to destryed objects
Toggle commit list -
resolved all discussions
Toggle commit list -
added 1 commit
- 6be9eb13 - installed-tests/js: add testGObjectDestructionAccess to verify access to destryed objects
Toggle commit list -
Developer
Updated as requested, I think it should good to go now :)
-
-
resolved all discussions
Toggle commit list -
merged
Toggle commit list -
Master
Thanks for all the work!
🎉 -
-
-
-
-
-