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 690851 - Fix out marshalling of C arrays in closures
Fix out marshalling of C arrays in closures
Status: RESOLVED FIXED
Product: pygobject
Classification: Bindings
Component: introspection
unspecified
Other All
: Normal normal
: ---
Assigned To: Nobody's working on this now (help wanted and appreciated)
Python bindings maintainers
Depends on: 727004
Blocks: 690377 690670
 
 
Reported: 2012-12-29 11:21 UTC by Paolo Borelli
Modified: 2014-08-08 01:02 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Fix out marshalling of C arrays (1.26 KB, patch)
2012-12-29 11:21 UTC, Paolo Borelli
needs-work Details | Review
g-i patch (2.69 KB, patch)
2013-01-10 21:26 UTC, Paolo Borelli
committed Details | Review
unit test (1.34 KB, patch)
2013-01-10 21:30 UTC, Paolo Borelli
reviewed Details | Review
(broken attempt) produce proper C arrays in _pygi_argument_from_object() (2.68 KB, patch)
2013-01-11 11:53 UTC, Martin Pitt
needs-work Details | Review
tests: Add tests for GApplication local command line handling (2.83 KB, patch)
2014-08-08 01:02 UTC, Simon Feltman
committed Details | Review

Description Paolo Borelli 2012-12-29 11:21:47 UTC
For plain C arrays we need to free the GArray and only return the actual
data.
Comment 1 Paolo Borelli 2012-12-29 11:21:50 UTC
Created attachment 232366 [details] [review]
Fix out marshalling of C arrays
Comment 2 Paolo Borelli 2012-12-29 11:23:39 UTC
This is needed to make it possible to implement GApplication::local_command_line vfunc. See https://bugzilla.gnome.org/show_bug.cgi?id=690670 for a patch adding the annotations to glib
Comment 3 Simon Feltman 2012-12-30 09:36:41 UTC
Review of attachment 232366 [details] [review]:

I think a corresponding check for GI_ARRAY_TYPE_C in _pygi_argument_release might also be needed to avoid an invalid g_array_free? A regression test for this and related situations would be nice if possible to make sure memory and references are handled correctly.
Comment 4 Martin Pitt 2012-12-30 10:41:21 UTC
This patch changes the type of the returned array (correctly, apparently). Although we have plenty of existing regression tests for all kinds of arrays already, we apparently don't have one for a C array in signal handlers (which would be what this code path touches apparently?); so I do agree that we should add a test for this.

Thanks!
Comment 5 Martin Pitt 2012-12-30 10:41:52 UTC
Comment on attachment 232366 [details] [review]
Fix out marshalling of C arrays

Setting to "needs work" as this needs the corresponding check in _release(), what Simon said.
Comment 6 Paolo Borelli 2013-01-10 21:26:21 UTC
Created attachment 233179 [details] [review]
g-i patch

Patch to g-i to create a testcase
Comment 7 Paolo Borelli 2013-01-10 21:30:13 UTC
Created attachment 233184 [details] [review]
unit test

Since Martin poked me today about this I quickly tried to create a testcase and it looks my patch is not enough to fix things: without my patch this test crashes, with my patch it does not crashes but it still fails... I am either doing something stupid in the test or more work is missing to marshal this array properly.

Help is very appreciated, I do not have much time to look into this and doing it in bits and pieces after dinner does not help :)
Comment 8 Martin Pitt 2013-01-11 05:56:52 UTC
Comment on attachment 233179 [details] [review]
g-i patch

Thanks for the test case, that's very helpful! The g-i patch looks good, please commit with a bug reference in the commit log, and maybe with a more textual summary ("gimarshallingtests: Add vfunc with an out array parameter")
Comment 9 Paolo Borelli 2013-01-11 08:55:20 UTC
Comment on attachment 233179 [details] [review]
g-i patch

pushed to g-i
Comment 10 Martin Pitt 2013-01-11 10:46:48 UTC
Keeping debug notes:

With Paolo's patch, the test case delivers [42.41999816894531, 0.0]. If I add a third array element, it comes out as [42.41999816894531, 0.0, 3.140000104904175], so somewhere it mishandles the size of the array elements.

Debugging _pygi_argument_from_object() for processing the returned python array from the vfunc shows that it's building a GArray of GIArguments that are all valid gfloats. Now we hit the place of Paolo's (slightly simplified) patch:

            if (g_type_info_get_array_type (type_info) == GI_ARRAY_TYPE_C)
                arg.v_pointer = g_array_free (array, FALSE);
            else
                arg.v_pointer = array;

In current pygobject, it would assign arg.v_pointer to a GArray of GIArgument, now it turns that into a GIArgument* C array.

Now, I'm not sure what the expected format of a returned array GIArgument is -- should it be an array of GIArgument (which seems to work for at least the GARRAY type), or a plain C array with the data? The test case seems to indicate the latter.
Comment 11 Martin Pitt 2013-01-11 10:49:38 UTC
To illustrate, that's the returned value in _pygi_closure_assign_pyobj_to_out_argument():

gdb) p ((GIArgument*) arg.v_pointer)[0]
$46 = {[...], v_float = 42.4199982, [...]}
(gdb) p ((GIArgument*) arg.v_pointer)[1]
$47 = {[...], v_float = 3.1400001, [...]}

While apparently it's expecting this format:

(gdb) p ((gfloat*) arg.v_pointer)[0]
$49 = 42.4199982
(gdb) p ((gfloat*) arg.v_pointer)[1]
$50 = 0
(gdb) p ((gfloat*) arg.v_pointer)[2]
$51 = 3.1400001
Comment 12 Martin Pitt 2013-01-11 11:53:48 UTC
Created attachment 233217 [details] [review]
(broken attempt) produce proper C arrays in _pygi_argument_from_object()

I just realized that this approach isn't going to work. If _pygi_argument_from_object() already produces plain C arrays, then we lose all length information for the caller. This would work for pointer arrays which can be NULL terminated, but it wouldn't work for this example of a gfloat[].

So I think we need to keep at least the GArray return here; I'm not decided yet whether or not the items should be GIArguments or direct values, but as for the "GArray" case they are GIArguments, they should probably stay that way for the "C array" case as well, and the distinction needs to happen in _pygi_closure_assign_pyobj_to_out_argument().

Attaching the broken patch for reference.
Comment 13 Martin Pitt 2013-01-14 09:05:01 UTC
Comment on attachment 233184 [details] [review]
unit test

This unit test needs some cleanup, but is by and large good. It is included in the next patch attachment which also contains an attempt to fix this.

For cleaning up the patch review queue I'll mark this as superseded.
Comment 14 Simon Feltman 2014-08-08 01:01:54 UTC
Closing now that bug 727004 is fixed and local_command_line vfuncs work.

The following fix has been pushed:
d689d24 tests: Add tests for GApplication local command line handling
Comment 15 Simon Feltman 2014-08-08 01:02:00 UTC
Created attachment 282857 [details] [review]
tests: Add tests for GApplication local command line handling

Add various tests which override Gio.Appliction.do_command_line and
do_local_command_line.