Tracking down and fixing a segfault in nautilus-python



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(). 

I'm hoping someone here with more experience with pygobject and/or nautilus has some insight into why this is happening, and a possible solution.

Thanks!

Adam Plumb


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]