Bug 29257

Summary: Crash in DBusPyException_ConsumeError when catching NameHasNoOwner
Product: dbus Reporter: Maciej Katafiasz <mathrick>
Component: pythonAssignee: Simon McVittie <smcv>
Status: RESOLVED WORKSFORME QA Contact: John (J5) Palmieri <johnp>
Severity: major    
Priority: medium Keywords: NEEDINFO
Version: unspecified   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:

Description Maciej Katafiasz 2010-07-26 01:54:30 UTC
The python bindings segfault in some situations when handling org.freedesktop.DBus.Error.NameHasNoOwner. This is due to the fact DBusPyException_ConsumeError:84 doesn't check exc before calling it with PyObject_SetAttrString, and sometimes exc can apparently be NULL. 

I'm not quire sure how that happens, but I hit it within an xchat python plugin making use of dbus to control Totem. If Totem exits, and there is a proxy object representing it, sometimes it will crash instead of catching the exception properly. So far I've been unable to reproduce that in pure python code.
Comment 1 Maciej Katafiasz 2010-07-28 13:30:08 UTC
OK, I think I've traced the root of the differences in the behaviour:

XChat uses one embedded python interpreter per python script, and reloading/unloading a script causes that interpreter to be destroyed. DBus-python very clearly does something wrong in this case, and causes things to crash and deadlock.

Here's a simple test case (save as ~/.xchat2/crasher.py)

__module_name__ = "crasher" 
__module_version__ = "0.1" 
__module_description__ = "Crash or lockup xchat by using dbus bindings"
__module_author__ = "Maciej Katafiasz <email@mathrick.org>"

import dbus

bus = dbus.SessionBus()
bus.close() # This call is crucial

print "Crasher loaded"

# To lock xchat up, /py unload crasher. It will deadlock trying to end the embedded interpreter

The above will lock up the intepreter:


Program received signal SIGINT, Interrupt.
0x0012d422 in __kernel_vsyscall ()
(gdb) bt
#0  0x0012d422 in __kernel_vsyscall ()
#1  0x009e5245 in sem_wait@@GLIBC_2.1 () from /lib/tls/i686/cmov/libpthread.so.0
#2  0x0169ce10 in PyThread_acquire_lock (lock=0x8be71d8, waitflag=1) at ../Python/thread_pthread.h:349
#3  0x0166c798 in PyEval_RestoreThread (tstate=0x8ada348) at ../Python/ceval.c:353
#4  0x0168fa90 in PyGILState_Ensure () at ../Python/pystate.c:592
#5  0x0180073f in ?? () from /usr/lib/pymodules/python2.6/_dbus_bindings.so
#6  0x009c6124 in ?? () from /lib/libdbus-1.so.3
#7  0x009c6172 in ?? () from /lib/libdbus-1.so.3
#8  0x009aca93 in ?? () from /lib/libdbus-1.so.3
#9  0x017fd898 in ?? () from /usr/lib/pymodules/python2.6/_dbus_bindings.so
#10 0x0162b5bd in subtype_dealloc (self=<SessionBus at remote 0x93a0cec>) at ../Objects/typeobject.c:1019
#11 0x0160c779 in insertdict (mp=0x90c83e4, key='bus', hash=-455024823, value=None) at ../Objects/dictobject.c:459
#12 0x0160f1c4 in PyDict_SetItem (op=
    {'dbus': None, '__builtins__': <module at remote 0x8eadac4>, 'bus': None, '__package__': None, 'sys': <module at remote 0x8eaddc4>, '__module_name__': 'crasher', '__module_description__': 'Crash or lockup xchat by using dbus bindings', '__name__': '__main__', '__module_author__': 'Maciej Katafiasz <email@mathrick.org>', '__doc__': None, '__module_version__': '0.1'}, 
    key='bus', value=None) at ../Objects/dictobject.c:701
#13 0x0161146e in _PyModule_Clear (m=<module at remote 0x8eadcbc>) at ../Objects/moduleobject.c:138
#14 0x016845c9 in PyImport_Cleanup () at ../Python/import.c:441
#15 0x01691355 in Py_EndInterpreter (tstate=0x8b9a478) at ../Python/pythonrun.c:642
#16 0x015988c6 in ?? () from /usr/lib/xchat/plugins/python.so
#17 0x0159ad98 in ?? () from /usr/lib/xchat/plugins/python.so
#18 0x0159c1c1 in ?? () from /usr/lib/xchat/plugins/python.so
#19 0x080a0b0c in ?? ()
#20 0x0809eaa6 in ?? ()
#21 0x0809f7ec in ?? ()
#22 0x08071c36 in ?? ()
#23 0x00a0adcc in g_cclosure_marshal_VOID__VOID () from /usr/lib/libgobject-2.0.so.0
#24 0x009fd252 in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
#25 0x00a1199d in ?? () from /usr/lib/libgobject-2.0.so.0
#26 0x001b7a62 in ?? () from /usr/lib/libgtk-x11-2.0.so.0
#27 0x001b801f in ?? () from /usr/lib/libgtk-x11-2.0.so.0
#28 0x001b82a2 in ?? () from /usr/lib/libgtk-x11-2.0.so.0
#29 0x001b83df in gtk_bindings_activate_event () from /usr/lib/libgtk-x11-2.0.so.0
#30 0x00203357 in ?? () from /usr/lib/libgtk-x11-2.0.so.0
#31 0x002802f4 in ?? () from /usr/lib/libgtk-x11-2.0.so.0
#32 0x009fb8b9 in ?? () from /usr/lib/libgobject-2.0.so.0
#33 0x009fd178 in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
#34 0x00a115e6 in ?? () from /usr/lib/libgobject-2.0.so.0
#35 0x00a12c33 in g_signal_emit_valist () from /usr/lib/libgobject-2.0.so.0
#36 0x00a13256 in g_signal_emit () from /usr/lib/libgobject-2.0.so.0
#37 0x003ad306 in ?? () from /usr/lib/libgtk-x11-2.0.so.0
#38 0x003bf27f in gtk_window_propagate_key_event () from /usr/lib/libgtk-x11-2.0.so.0
#39 0x003c259c in ?? () from /usr/lib/libgtk-x11-2.0.so.0
#40 0x002802f4 in ?? () from /usr/lib/libgtk-x11-2.0.so.0
#41 0x009fb8b9 in ?? () from /usr/lib/libgobject-2.0.so.0
#42 0x009fd252 in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
#43 0x00a115e6 in ?? () from /usr/lib/libgobject-2.0.so.0
#44 0x00a12c33 in g_signal_emit_valist () from /usr/lib/libgobject-2.0.so.0
#45 0x00a13256 in g_signal_emit () from /usr/lib/libgobject-2.0.so.0
#46 0x003ad306 in ?? () from /usr/lib/libgtk-x11-2.0.so.0
#47 0x00278a03 in gtk_propagate_event () from /usr/lib/libgtk-x11-2.0.so.0
#48 0x00279cd7 in gtk_main_do_event () from /usr/lib/libgtk-x11-2.0.so.0
#49 0x0056e35a in ?? () from /usr/lib/libgdk-x11-2.0.so.0
#50 0x00c135e5 in g_main_context_dispatch () from /lib/libglib-2.0.so.0
#51 0x00c172d8 in ?? () from /lib/libglib-2.0.so.0
#52 0x00c17817 in g_main_loop_run () from /lib/libglib-2.0.so.0
#53 0x0027a299 in gtk_main () from /usr/lib/libgtk-x11-2.0.so.0
#54 0x0806167b in ?? ()
#55 0x080ae7af in ?? ()
#56 0x00cb8bd6 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6
#57 0x08055c71 in ?? ()

This is a different crash than the first one I reported, but it has a very small testcase. It does not lockup if bus.close() isn't called. Similarly, calling bus.close() in the original plugin I found crashes in jumped from being pretty random to completely reproducible as soon as I tried closing the bus in the (vain, obviously) hope of fixing the crashes.
Comment 2 Simon McVittie 2010-12-02 09:41:04 UTC
(In reply to comment #0)
> The python bindings segfault in some situations when handling
> org.freedesktop.DBus.Error.NameHasNoOwner. This is due to the fact
> DBusPyException_ConsumeError:84 doesn't check exc before calling it with
> PyObject_SetAttrString, and sometimes exc can apparently be NULL.

I've added a check for that.

(In reply to comment #1)
> XChat uses one embedded python interpreter per python script, and
> reloading/unloading a script causes that interpreter to be destroyed.
> DBus-python very clearly does something wrong in this case

Bug #23831 caused something to be done wrong in finalizing/re-initializing an interpreter. Could you try again with dbus-python git master, or 0.83.2 when available, in which that bug is fixed?
Comment 3 Simon McVittie 2012-05-09 07:25:39 UTC
In the absence of testing information I'm closing this as WORKSFORME. Please reopen, or open a new bug, if there are further problems.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.