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 691753 - segfault on methods returning GValues of type GValue and no value
segfault on methods returning GValues of type GValue and no value
Status: RESOLVED OBSOLETE
Product: pygobject
Classification: Bindings
Component: gobject
Git master
Other Linux
: Normal normal
: ---
Assigned To: Nobody's working on this now (help wanted and appreciated)
Python bindings maintainers
Depends on:
Blocks:
 
 
Reported: 2013-01-15 00:21 UTC by Olivier Crête
Modified: 2018-01-10 20:21 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Olivier Crête 2013-01-15 00:21:59 UTC
To reproduce:

from gi.repository import GObject
v = GObject.Value()
v2 = GObject.Value(GObject.Value.__gtype__, v)
Comment 1 Martin Pitt 2013-01-17 07:52:34 UTC
In particular, this happens for

v = GObject.Value()
v.init(GObject.TYPE_VALUE)

The init() call crashes on a NULL pointer:

  • #0 pyg_value_as_pyobject
    at pygtype.c line 1118
  • #1 pyg_value_as_pyobject
    at pygtype.c line 1213

here:

        } else if (G_VALUE_HOLDS(value, G_TYPE_VALUE)) {
            GValue *n_value = g_value_get_boxed (value);
            return pyg_value_as_pyobject(n_value, copy_boxed);

(gdb) call g_value_get_boxed(value)
$4 = (void *) 0x0

and pyg_value_as_pyobject() does not work with NULL pointers (deliberately).
Comment 2 Martin Pitt 2013-01-17 10:31:55 UTC
This code was introduced in commit fe3966c2, for transparently "unpacking" GValues that are returned by functions. We want to keep this behaviour, both for backwards compatibility as well as for convenience (in most cases we don't want to deal with GValue objects in Python).

But this crashes as g_type_init() returns a GValue which has a data type, but a NULL v_pointer because it hasn't been set yet.
Comment 3 Martin Pitt 2013-01-17 10:48:28 UTC
If a method returns a GValue*, which has a properly set value, then pygobject should continue to transparently unwrap this, as discussed in the previous comment.

For handling returned GValues* which are not initialized or initialized without a set value, we can either (1) return (a python wrapper of) the GValue itself, or (2) return None. (1) seems a bit magic to me, as the return type of a method would then depend on the status of the GValue; (2) seems more consistent with what PyGObject does at the moment, but loses some information to the caller, in particular to which gtype the GValue was initialized.

By and large, I'm still favoring (2) at the moment, though. Opinions?
Comment 4 Martin Pitt 2013-01-18 17:10:34 UTC
I have another idea: Instead of doing the heuristic (1), and the problematic (2) (you'll run into type compatibility issues everywhere, I tried), we could limit this to g_value_init() only. As far as I can see this should be the only (or at least one of the very few) functions which actually return a GValue with a NULL value.

So we could just (skip) the return value of g_value_init(); but I have a feeling that the GLib guys might not like that, and indeed other interpreters like JS might not have the same automatic GValue conversion that pygobjejct has. Or we could write a static Python wrapper for g_value_init() in gi/_gobject/ which just returns None.
Comment 5 Martin Pitt 2013-01-21 21:50:42 UTC
I got a bit further with this. For the record, g_value_set_boxed() and g_value_get_boxed() also need static overrides as the C API just takes gconstpointers which GI cannot translate to "boxed interface" right now.
Comment 6 Simon Feltman 2013-01-21 22:23:58 UTC
Can the methods be annotated as taking a generic "Boxed" as the arg?

Also, at some point I think it will be worth exposing raw pointers to Python for the static G types (as a private attribute). This way we can work around needing special case static bindings for anything taking raw pointers and simply use an override instead. For instance:

class Value(GObject.Value):
    def set_boxed(self, boxed):
        return super().set_boxed(boxed._gptr)

That can at least work well for input args which take a gpointer, output args will be more difficult. I have been thinking about this for solving bug 633999 if we cannot annotate signal methods as Object.
Comment 7 GNOME Infrastructure Team 2018-01-10 20:21:42 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/pygobject/issues/41.