GNOME Bugzilla – Bug 642300
GByteArrays are sometimes reported as GPtrArrays
Last modified: 2015-02-07 17:01:07 UTC
Using NetworkManager introspection, I found that libgirepository (or g-ir-compiler?) is sometimes reporting GByteArray as GPtrArray, causing GJS to fail, because it cannot handle a GPtrArray of gpointer. I reproduced manually using libgirepository directly (using an empty program that just inited GType): (gdb) call g_irepository_get_default() $1 = (GIRepository *) 0x60b400 (gdb) call g_irepository_require($1, "NetworkManager", NULL, 0, NULL) No symbol "NULL" in current context. (gdb) call g_irepository_require($1, "NetworkManager", 0, 0, 0) $2 = (GITypelib *) 0x60be00 (gdb) call g_irepository_find_by_name($1, "NetworkManager", "SettingWired") $3 = (GIBaseInfo *) 0x6032d0 (gdb) call g_object_info_get_n_methods($3) $4 = 15 (gdb) call g_object_info_find_method($3, "get_mac_address") $5 = (GIFunctionInfo *) 0x603320 (gdb) call g_callable_info_get_return_type($5) $6 = (GITypeInfo *) 0x603370 (gdb) call g_type_info_get_tag($6) $7 = GI_TYPE_TAG_ARRAY (gdb) call g_type_info_get_array_type($6) $8 = GI_ARRAY_TYPE_PTR_ARRAY The relevant and correct GIR snippet is: <method name="get_mac_address" c:identifier="nm_setting_wired_get_mac_address"> <return-value transfer-ownership="none"> <array name="GLib.ByteArray" c:type="GByteArray*"> <type name="gpointer" c:type="gpointer"/> </array> </return-value> </method>
Can you paste a link to the C code?
What C code? The NetworkManager function? It is at http://cgit.freedesktop.org/NetworkManager/NetworkManager/tree/libnm-util/nm-setting-wired.c?h=rm-userset#n153 The test case instead is int main() { g_type_init(); raise(SIGTRAP); }, plus manual function calls in Gdb.
Found the bug, it was in the typelib compilation, in the part of converting the AST to the actual bytes. In particular, when emitting a GIrNodeType, it prefers to emit a reference if the same type has already been emitted, and to do this it serializes it and looks it up in a hash table. The problem is that all kind of arrays (C, GByteArray, GPtrArray, GArray all were serialized in the same way, so the first seen one with the same signature would win, even if it was of a different type. Practically, this resulted in emitting a reference to a GPtrArray of void* instead of a GByteArray. Patch coming.
Created attachment 181244 [details] [review] GIrNode: fix lookup of cached type nodes Different types of array have different type nodes, so they should produce different keys in the cache of already seen type nodes, to avoid turning a GByteArray into a reference to a GPtrArray.
Review of attachment 181244 [details] [review]: Hmm, so we have been generating corrupted typelibs up till now; ouch. I guess since it just affects these array types it's not crippling - we can let them get rebuilt over time. This patch looks right to me though, thanks for tracking down the bug!
Attachment 181244 [details] pushed as e16444d - GIrNode: fix lookup of cached type nodes
[Mass-moving gobject-introspection tickets to its own Bugzilla product - see bug 708029. Mass-filter your bugmail for this message: introspection20150207 ]