Hi All:

I work on Orca, which is an open source screen reader for people with
visual impairments for the GNOME platform.  Orca is written entirely in
Python and communicates with desktop applications via ORBit/bonobo and
the AT-SPI.  

I need some help trying to track down some random hangs in Orca.  I've
been trying to debug these by analyzing gdb traces and such.  These have
led little insight, except to say "yep, looks like someone's waiting to
get a lock".  I was lucky to catch an actual hang and was able to get a
stack trace in the debugger.  Here's a snippet:

Thread 1 (Thread -1210829120 (LWP 20818)):
#0  0xffffe410 in __kernel_vsyscall ()
#1  0xb7f83c76 in pthread_cond_wait@@GLIBC_2.3.2 ()
   from /lib/tls/i686/cmov/libpthread.so.0
#2  0xb6f2d595 in giop_recv_buffer_get () from /usr/lib/libORBit-2.so.0
#3  0xb6f30cc5 in ORBit_small_invoke_stub ()
from /usr/lib/libORBit-2.so.0
#4  0xb6eb589f in pycorba_method_call (self=0xb6d7dcf8, args=0xb62a192c,
    kwargs=0x0) at pycorba-method.c:323
#5  0xb6eb5d40 in pycorba_bound_method_call (self=0xb6d7dfc8,
args=0xb62a192c,
    kwargs=0xfffffffc) at pycorba-method.c:500
#6  0x0805e2fb in PyObject_Call (func=0xb6d7dfc8, arg=0xb7d03034,
kw=0x0)
    at Objects/abstract.c:1795

I've also been able to create a small standalone application that seems
to create a hang when it runs bonobo.main from a separate thread.  The
stack trace I get from it is a bit different from the above, but I'm
hoping the application might lend some insight into what might be
happening. All the app does is run bonobo.main from a separate thread
(see lines 92 and 99 from the attached file).  When this app is running
and one interacts with an AT-SPI friendly application (e.g., clicking on
buttons in gnome-terminal), the entire desktop will hang.  Here's a
snippet from its stack trace when it is hung:

Thread 1 (Thread -1211324736 (LWP 31309)):
#0  0xffffe410 in __kernel_vsyscall ()
#1  0xb7f0caf0 in [EMAIL PROTECTED] ()
from /lib/tls/i686/cmov/libpthread.so.0
#2  0x081c6288 in ?? ()
#3  0x08106947 in PyThread_acquire_lock (lock=0x82abfc8, waitflag=1)
    at thread_pthread.h:313
#4  0x08109a27 in lock_PyThread_acquire_lock (self=0xb7817780,
args=0xb7c8a034)
    at ./Modules/threadmodule.c:63
#5  0x0812fac2 in PyCFunction_Call (func=0xb760629c, arg=0xb7c8a034,
kw=0x0)
    at Objects/methodobject.c:73
...

I'm curious if anyone might be able to lend some insight here - our
users get very frustrated when the entire desktop hangs and goes
silent.  :-(

Will

"""Simple test app that hangs when bonobo.main is run in its own
thread.  To reproduce the hang:

1) Run this application in an xterm
2) Run a gnome-terminal
3) Click on the file menu of the gnome-terminal

The desktop will hang every time.
"""


import threading

import bonobo
import ORBit

ORBit.load_typelib("Accessibility")
ORBit.CORBA.ORB_init()

import Accessibility
import Accessibility__POA

import gobject
import gtk

listeners = []

registry = bonobo.get_object("OAFIID:Accessibility_Registry:1.0",
                             "Accessibility/Registry")

class EventListener(Accessibility__POA.EventListener):
    def __init__(self, registry, callback, eventType):
        self.registry  = registry
        self.callback  = callback
        self.eventType = eventType
        self.register()

    def ref(self): pass

    def unref(self): pass

    def queryInterface(self, repo_id):
	thiz = None
        if repo_id == "IDL:Accessibility/EventListener:1.0":
            thiz = self._this()
	return thiz

    def register(self):
        self._default_POA().the_POAManager.activate()
        self.registry.registerGlobalEventListener(self._this(),
                                                  self.eventType)
        self.__registered = True
        return self.__registered

    def deregister(self):
        if not self.__registered:
            return
        self.registry.deregisterGlobalEventListener(self._this(),
                                                    self.eventType)
        self.__registered = False

    def notifyEvent(self, event):
        try:
            self.callback(event)
        except:
            print "OOPS!"
        return True
    
    def __del__(self):
        self.deregister()

def registerEventListener(callback, eventType):
    global listeners
    listener = EventListener(registry, callback, eventType)
    listeners.append(listener)

def notifyEvent(event):
    print "notifyEvent"

def shutdownAndExit(signum=None, frame=None):
    print "shutdownAndExit"
    for listener in (listeners):
        listener.deregister()
    bonobo.main_quit()
    
class _BonoboMainThread(threading.Thread):
    def run(self):
        print "BONOBO MAIN THREAD RUN CALLED"
        #gobject.threads_init()
        #gtk.gdk.threads_init()
        #gtk.gdk.threads_enter()
        bonobo.main()
        #gtk.gdk.threads_leave()
        print "BONOBO MAIN THREAD FINISHING"
    
def test():
    registerEventListener(notifyEvent, "focus:")

    if True:
        _BonoboMainThread().start()
        print "BONOBO MAIN THREAD START CALLED"
    else:
        print "CALLING BONOBO MAIN"
        #gobject.threads_init()
        #gtk.gdk.threads_init()
        #gtk.gdk.threads_enter()
        bonobo.main()
        #gtk.gdk.threads_leave()
        print "BONOBO MAIN COMPLETED"
        
if __name__ == "__main__":
    import signal
    signal.signal(signal.SIGINT, shutdownAndExit)
    signal.signal(signal.SIGQUIT, shutdownAndExit)
    test()
_______________________________________________
pygtk mailing list   pygtk@daa.com.au
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/

Reply via email to