GNOME Bugzilla – Bug 654564
Querying EDS address book in Python results in a segfault
Last modified: 2014-01-28 07:25:40 UTC
When accessing EDS address book the code below will successfully crash python and no contact list is obtained. :( from gi.repository import EBook book = EBook.Book.new_system_addressbook() # ?? book.open(book) contactlist = [] field = EBook.ContactField.FULL_NAME fieldtest = EBook.BookQueryTest.BEGINS_WITH query = EBook.book_query_field_test(field, fieldtest, "John") status = EBook.Book.get_contacts(book, query, contactlist) Tested on the latest Ubuntu Oneiric.
Stacktrace is very welcome.
Sorry for the late reply, but here's the backtrace as gdb reports it:
+ Trace 227862
The introspection stuff just maps the C API, so there is nothing in between that translates from a Python list to a GSList, which is what get_contacts_sync expects. Also, you need to pass all arguments the C API expects, as not doing so will send uninitialized values to the C API. So: EBook.BookClient.get_contacts_sync(client, query_string, contactlist, None, None) and contactlist needs to be a GSList.
This looks indeed like a problem in pygobject, as it seems this function, should work like this in Python: (ret, contacts) = book.get_contacts_sync(client, sexp) as explained here: https://live.gnome.org/PyGObject/IntrospectionPorting#Output_arguments so, I'd say this needs to be reported to PyGObject
The non-working code in question and the result are below: #!/usr/bin/python from gi.repository import EBook contacts = [] client = EBook.BookClient.new_system() query_string = "(contains \"full_name\" \"N\")" ret = EBook.BookClient.get_contacts_sync(client, query_string, contacts, None) print contacts if not ret: print "*sob*" --- bigwhale@thefish:~/Code/Gwibber/eds$ ./python-eds-1.py (process:23434): libebook-CRITICAL **: e_book_client_get_contacts_sync: assertion `contacts != NULL' failed [] *sob* bigwhale@thefish:~/Code/Gwibber/eds$
But an empty GSList is NULL so how can contacts allow empty lists without accepting NULL?
Oh, so the contacts list is an out value. Can you please post the relevant section the EBook .gir file? The part that describes the get_contacts_sync method
<method name="get_contacts_sync" c:identifier="e_book_client_get_contacts_sync" version="3.2" throws="1"> <doc xml:whitespace="preserve">Query @client with @sexp, receiving a list of contacts which matched. If successful, then the @contacts is set to newly allocated #GSList of #EContact-s, which should be freed with e_client_util_free_object_slist(). to a string with e_book_query_to_string().</doc> <return-value transfer-ownership="none"> <doc xml:whitespace="preserve">%TRUE if successful, %FALSE otherwise.</doc> <type name="gboolean" c:type="gboolean"/> </return-value> <parameters> <parameter name="sexp" transfer-ownership="none"> <doc xml:whitespace="preserve">an S-expression representing the query</doc> <type name="utf8" c:type="gchar*"/> </parameter> <parameter name="contacts" transfer-ownership="none"> <doc xml:whitespace="preserve">(out) a #GSList of matched #EContact-s</doc> <type name="GLib.SList" c:type="GSList**"> <type name="gpointer" c:type="gpointer"/> </type> </parameter> <parameter name="cancellable" transfer-ownership="none" allow-none="1"> <doc xml:whitespace="preserve">a #GCancellable; can be %NULL</doc> <type name="Gio.Cancellable" c:type="GCancellable*"/> </parameter> </parameters> </method> the .gir file contents
(out) a #GSList of matched #EContact-s needs to be (out): a #GSList of matched #EContact-s You are missing a colon in the docstring
Created attachment 212630 [details] Test case Running the attached test case results in a crash using pygobject 3.2.0 on Fedora 17:
+ Trace 230124
Ignore the previous stacktrace, I was missing debug symbols.
+ Trace 230125
Cannot reproduce in e-d-s 3.7.4, the following code works: from gi.repository import EDataServer from gi.repository import EBook registry = EDataServer.SourceRegistry.new_sync(None) source = registry.ref_default_address_book() address_book = EBook.BookClient.new(source) address_book.open_sync(False, None) query_string = '(contains "full_name" "N")' ret, contacts = EBook.BookClient.get_contacts_sync(address_book, query_string, None) print contacts print ret
Sebastian's example in comment 10 doesn't seem to work with eds 3.6.x any more: Traceback (most recent call last):
+ Trace 231580
book = EBook.Book.new_system_addressbook()
Vadim's example from comment 12 works fine with eds 3.6.x as well. So is this still actually an issue? Have e-d-s' annotations been fixed (see John's comment 9)?
Closing since there seems to be working code noted in comment 12