Re: Tracking down and fixing a segfault in nautilus-python
- From: Adam Plumb <adamplumb gmail com>
- To: nautilus-list gnome org
- Subject: Re: Tracking down and fixing a segfault in nautilus-python
- Date: Tue, 19 Jan 2010 13:18:44 -0500
On Tue, Jan 19, 2010 at 11:00 AM, Alexander Larsson
<alexl redhat com> wrote:
On Mon, 2010-01-18 at 11:25 -0500, Adam Plumb wrote:
> hi all, I'm working on tracking down the root cause of a segfault in
> nautilus/nautilus-python/pygobject that is actually quite easily
> reproducible. I'm the maintainer for nautilus-python and have been
> working all weekend trying to figure this out and find a way to fix
> it.
>
> To reproduce, install nautilus-python, then install this python script
> in your ~/.nautilus/python-extensions folder:
>
> import nautilus
> class Test(nautilus.MenuProvider):
> def __init__(self):
> print "Init Test Plugin"
> pass
> def get_background_items(self, window, folder):
> return []
>
>
> Then from the command line kill nautilus (nautilus -q) and run without
> a desktop (nautilus --no-desktop). Make sure the python plugin has
> been loaded, then navigate to any XDG folder (Documents, Downloads,
> Music, Pictures, etc). Then quit out of nautilus. You will always
> see a segfault with the following trace:
>
> (gdb) bt
> #0 PyThreadState_New (interp=0x0) at ../Python/pystate.c:201
> #1 0x00007fffeb7eb90c in PyGILState_Ensure ()
> at ../Python/pystate.c:581
> #2 0x00007fffeab96a10 in ?? ()
> from /usr/lib/pymodules/python2.6/gtk-2.0/gobject/_gobject.so
> #3 0x00007ffff382f232 in g_datalist_clear ()
> from /lib/libglib-2.0.so.0
> #4 0x00007ffff3f2052f in g_object_unref ()
> from /usr/lib/libgobject-2.0.so.0
> #5 0x00000000004ca231 in free_xdg_dir_cache () at
> nautilus-file-utilities.c:344
> #6 0x00000000004ca2d7 in destroy_xdg_dir_cache () at
> nautilus-file-utilities.c:357
> #7 0x000000000051f448 in eel_debug_shut_down () at eel-debug.c:109
> #8 0x0000000000444694 in main (argc=1, argv=0x7fffffffe368) at
> nautilus-main.c:554
>
>
> Here is what is happening. When you navigate to an XDG folder,
> get_background_items is called on the folder (this gets a list of menu
> items for the context menu) and a new pygobject is created for the
> folder (to pass from nautilus-python to the plugin script). When
> nautilus is shut down, it calls nautilus-python's
> nautilus_module_shutdown() function, which in turn finalizes its
> python intepreter (with Py_Finalize()). However, after module is shut
> down, nautilus tries to free its XDG dir cache, which contains some
> sort of pygobject data, because line #2 of the bt is a call to
> pygobject_data_free, which makes a call to pyglib_gil_state_ensure()
> before it can free its data. Hence the segfault on the NULL interp
> object (Which has already been finalized)
>
> So those are the bare facts. The part that I'm stuck on is why the
> XDG folders' NautilusFile object is hanging on to a PyGObject object
> (from get_background_items) when it should have been freed earlier,
> either at the end of the get_background_items call or during
> Py_Finalize().
It seems that something did a g_object_set_data() on the NautilusFile
object, attaching some python object, passing in a destroy notifier that
probably unrefs the python object which is called when the NautilusFile
is freed. However, this then gets called after python is un-initialized
because the user data was not unset.
You need to figure out first what is setting this user data, and
secondly why its not cleared before finalizing python.
I mistakenly sent my response directly back to Alex, here it is for the mailing list.
The user data is getting set by pygobject when the get_background_items
function converts the NautilusFileInfo object to a pygobject (with
pygobject_new). When a PyGObject is created, it in turn calls
g_object_set_qdata_full(), which in turn calls
g_datalist_id_set_data_full(), which in turn calls
g_data_set_internal(), which I'm guessing is what is attaching the user
data.
I think the reason why the objects are not getting freed is that
the NautilusFile objects that are XDG folders are getting cached
somehow, and the objects don't get freed until nautilus is shutdown
(after nautilus-python, and the python interpreter, gets shut down).
I'm thinking I may have to track these NautilusFile objects and
free that data manually before shutting down the python interpreter. I
will try that and see how it works.
.... here is my second response five minutes later....
Sweet!
That was exactly it. I was able to set the pygobject
instance data to NULL directly after making the call to the python
plugin in get_background_items. The exact call I made was:
g_object_set_data(file, "PyGObject::instance-data", NULL);
This
got rid of the segmentation fault, since the instance data was no
longer being held until the very end in the XDG folder objects.
Adam
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]