[PyKDE] QCustomEvent Subclass and Seg Faults

Troy Melhase troy at gci.net
Tue Jun 17 00:02:01 BST 2003


Hi All:

I have a QCustomEvent class that's somehow related to intermittant segfaults.  
My app ismulti-threaded, and one of the threads reads socket data, turns the 
data into an object,and delivers the object to other interested objects.

The socket-reader thread calls methods of a proxy class, listed below.  These 
methods then create the QCustomEvent subclass instances and post them to the 
application.  Here's the proxy and it's helper function:

def mk_signal(signal_name):
    def inner_ib_method(self, event):
        self.count_incoming()
	## this creates an instance of the custom event subclass
	## 'event' is the object created by the socket reader thread
        broker_event = BrokerSocketDataEvent(signal_name, event)
	try:
            QApplication.postEvent(self.parent, broker_event)
        except AttributeError:
            pass
    return inner_ib_method

class BrokerEventGuiProxy(QObject):
    def __init__(self, parent, connection):
        self.parent = parent
        self.message_counters = {}

    def count_incoming(self):
        hour = time.localtime()[3]
        self.message_counters.setdefault(hour, 0)
        self.message_counters[hour] += 1

    ib_account = mk_signal('BrokerUpdateAccountValue')
    ib_error = mk_signal('BrokerError')
    ib_execution_details = mk_signal('BrokerExecutionDetails')
    ib_open_order = mk_signal('BrokerOpenOrder')
    ib_order_status = mk_signal('BrokerOrderStatus')
    ib_ticker = mk_signal('BrokerTickerMessage')
    ib_market_depth = mk_signal('BrokerUpdateMarketDepth')
    ib_portfolio = mk_signal('BrokerUpdatePortfolio')
    ib_reader_stop = mk_signal('BrokerDisconnected')

And here is the QCustomEvent subclass:

class BrokerSocketDataEvent(QCustomEvent):
    names = ['BrokerError',
             'BrokerExecutionDetails',
             'BrokerOpenOrder',
             'BrokerOrderStatus',
             'BrokerTickerMessage',
             'BrokerUpdateAccountValue',
             'BrokerUpdateMarketDepth',
             'BrokerUpdatePortfolio',
             'BrokerDisconnected', ]
    names_lookup = dict(zip(names, range(QEvent.User, \
    	QEvent.User + len(names))))

    def __init__(self, name, data):
        event_key = self.names_lookup[name]
        QCustomEvent.__init__(self, event_key, (name, data))


In my main window, I have a customEvent method defined to handle
these events:

    def customEvent(self, event):
        if isinstance(event, (BrokerSocketDataEvent, )):
            sig, broker_signal = event.data()
            self.emit(PYSIGNAL(sig), (broker_signal, ))


Typically, this app processes about 10-15 of these objects per second.
Sometimes the app will segfault after just a few hours, sometimes not at all.  
There doesn't seem to be a repeatable sequence of user actions that causes the
behavior.

Originally, I was propagating the objects by first acquiring the Qt library
mutex and calling GUI object methods directly.  This worked and never caused a
segfault, but chewed up 10% more CPU and made the GUI feel much less 
responsive.  Those reasons led me to the proxy solution above.

Interestingly, the BrokerSocketDataEvent objects never get garbage collected 
-- I'm not certain if that'srelated to the segfaults or not.  When this app 
is run without any GUI, I don't see any leaks --the gc counts look constant.  
In the GUI code, I'm not explicitly maintaining a reference to the event 
objects as they're processed, so I'm at a loss to explain this behavior as 
well.

I'm using Python 2.3b1, Qt 3.1.2, PyQt and SIP 3.6, gcc 3.2.2.  I'm a babe 
lost in the woods when it comes to debugging and debugging python extensions, 
so please forgive me if I've omitted something or stated something 
incorrectly.

Any ideas?  Suggestions?  Am I doing something obviously wrong?  Known or 
fixed bug?  Thanks.

-troy

backtrace:


(gdb) bt full
#0  0x4125979f in sipDo_QCustomEvent_data(_object*, _object*) ()
   from /home/troy/local/python2.3/lib/python2.3/site-packages/libqtcmodule.so
No symbol table info available.
#1  0x080f60aa in PyCFunction_Call (func=0x3e9, arg=0x4149f0d8, kw=0x1) at
Objects/methodobject.c:108        meth = (struct _object *(*)(struct _object 
*,
struct _object *)) 0x41259730 <sipDo_QCustomEvent_data(_object*, _object*)>
  self = (struct _object *) 0x4b0fc220        size = 0
#2  0x080a975d in call_function (pp_stack=0xbfffea7c, oparg=0) at
Python/ceval.c:3416        callargs = (struct _object *) 0x4b0fc220
        flags = 0
        na = 1259323936
        nk = 1001
        n = 0
        pfunc = (struct _object **) 0x8a8d000
        func = (struct _object *) 0x4149f0d8
        x = (struct _object *) 0x3e9
        w = (struct _object *) 0x1
#3  0x080a7c97 in eval_frame (f=0x8a8cea4) at Python/ceval.c:2093
        stack_pointer = (struct _object **) 0x8a8d004
        next_instr = (unsigned char *) 0x402d4a10 "\\\002"
        opcode = 131
        oparg = 0
        why = WHY_NOT
        err = 0
        x = (struct _object *) 0x4b0ff24c
        v = (struct _object *) 0x83
        w = (struct _object *) 0x402d17e0
        u = (struct _object *) 0x8a8d004
        t = (struct _object *) 0x402d49f4
        stream = (struct _object *) 0x0
        fastlocals = (struct _object **) 0x8a8cff0
        freevars = (struct _object **) 0x8a8d000
        retval = (struct _object *) 0x0
        tstate = (struct _ts *) 0x8132d28
        co = (struct {...} *) 0x403137e0
        instr_ub = -1
        instr_lb = 0
        first_instr = (unsigned char *) 0x402d49f4 "t"
        names = (struct _object *) 0x402f726c
        consts = (struct _object *) 0x4037914c
#4  0x080a869c in PyEval_EvalCodeEx (co=0x403137e0, globals=0x1, locals=0x0, 
args=0x8a8cea4, argcount=2, kws=0x0, kwcount=0,    defs=0x0, defcount=0, 
closure=0x0) at Python/ceval.c:2640        f = (struct _frame *) 0x8a8cea4
        retval = (struct _object *) 0x0
        fastlocals = (struct _object **) 0x8a8cff0
        freevars = (struct _object **) 0x8a8d000
        tstate = (struct _ts *) 0x8132d28
        x = (struct _object *) 0x1
        u = (struct _object *) 0x4b0fc2cc
#5  0x080f5c69 in function_call (func=0x403b75dc, arg=0x4b0a464c, kw=0x0) at 
Objects/funcobject.c:501        result = (struct _object *) 0x403b75dc
        argdefs = (struct _object *) 0x403b75dc
        d = (struct _object **) 0x0
        k = (struct _object **) 0x0
        nk = 1077638620
        nd = 0
#6  0x0805b539 in PyObject_Call (func=0x8132d28, arg=0x0, kw=0x0) at 
Objects/abstract.c:1755        call = (struct _object *(*)(struct _object *, 
struct _object *, struct _object *)) 0x1#7  0x08061cc8 in instancemethod_call 
(func=0x403b75dc, arg=0x4b0a464c, kw=0x0) at Objects/classobject.c:2432        
self = (struct _object *) 0x403b614c        class = (struct _object *) 
0x403a023c        result = (struct _object *) 0x403a023c
#8  0x0805b539 in PyObject_Call (func=0x8132d28, arg=0x0, kw=0x0) at 
Objects/abstract.c:1755        call = (struct _object *(*)(struct _object *, 
struct _object *, struct _object *)) 0x1#9  0x080a94e5 in 
PyEval_CallObjectWithKeywords (func=0x0, arg=0x4b0a464c, kw=0x0) at 
Python/ceval.c:3323        result = (struct _object *) 0x0#10 0x40022eb4 in 
sipEvalMethod () from 
/home/troy/local/python2.3/lib/python2.3/site-packages/libsip.soNo symbol 
table 
info available.#11 0x4133bb6f in sipQObject::sipVH_customEvent(sipMethodCache 
const*, _sipThisType*, QCustomEvent*) ()   from 
/home/troy/local/python2.3/lib/python2.3/site-packages/libqtcmodule.soNo 
symbol 
table info available.#12 0x41158c8e in 
sipQMainWindow::customEvent(QCustomEvent*) ()   from 
/home/troy/local/python2.3/lib/python2.3/site-packages/libqtcmodule.soNo 
symbol 
table info available.#13 0x4060d22c in QObject::event(QEvent*) () from 
/usr/qt/3/lib/libqt-mt.so.3No symbol table info available.#14 0x4064388c in 
QWidget::event(QEvent*) () from /usr/qt/3/lib/libqt-mt.so.3No symbol table 
info 
available.#15 0x406eafe2 in QMainWindow::event(QEvent*) () from 
/usr/qt/3/lib/libqt-mt.so.3No symbol table info available.
#16 0x411591cf in sipQMainWindow::event(QEvent*) () from 
/home/troy/local/python2.3/lib/python2.3/site-packages/libqtcmodule.soNo 
symbol 
table info available.#17 0x405b1644 in QApplication::internalNotify(QObject*, 
QEvent*) () from /usr/qt/3/lib/libqt-mt.so.3No symbol table info available.
#18 0x405b0bbb in QApplication::notify(QObject*, QEvent*) () from 
/usr/qt/3/lib/libqt-mt.so.3No symbol table info available.
#19 0x4132f13b in sipQApplication::notify(QObject*, QEvent*) ()
   from /home/troy/local/python2.3/lib/python2.3/site-packages/libqtcmodule.so
No symbol table info available.
#20 0x405b23d8 in QApplication::sendPostedEvents(QObject*, int) () from 
/usr/qt/3/lib/libqt-mt.so.3No symbol table info available.
#21 0x405b2258 in QApplication::sendPostedEvents() () from 
/usr/qt/3/lib/libqt-mt.so.3No symbol table info available.
#22 0x40569c15 in QEventLoop::processEvents(unsigned) () from 
/usr/qt/3/lib/libqt-mt.so.3No symbol table info available.
#23 0x405c5466 in QEventLoop::enterLoop() () from /usr/qt/3/lib/libqt-mt.so.3
No symbol table info available.
#24 0x405c5308 in QEventLoop::exec() () from /usr/qt/3/lib/libqt-mt.so.3
No symbol table info available.
#25 0x405b1871 in QApplication::exec() () from /usr/qt/3/lib/libqt-mt.so.3
No symbol table info available.
#26 0x413314fb in sipDo_QApplication_exec_loop(_object*, _object*) ()
   from /home/troy/local/python2.3/lib/python2.3/site-packages/libqtcmodule.so
No symbol table info available.
#27 0x080f60aa in PyCFunction_Call (func=0x826a8e0, arg=0x40a10128, kw=0x1) at 
Objects/methodobject.c:108        meth = (struct _object *(*)(struct _object 
*, 
struct _object     *)) 0x41331480 <sipDo_QApplication_exec_loop(_object*, 
_object*)>        self = (struct _object *) 0x403b63e0
        size = 0
#28 0x080a975d in call_function (pp_stack=0xbffff43c, oparg=0) at 
Python/ceval.c:3416        callargs = (struct _object *) 0x403b63e0
        flags = 0
        na = 1077634016
        nk = 136751328
        n = 0
        pfunc = (struct _object **) 0x8188528
        func = (struct _object *) 0x40a10128
        x = (struct _object *) 0x826a8e0
        w = (struct _object *) 0x1
#29 0x080a7c97 in eval_frame (f=0x81883dc) at Python/ceval.c:2093
        stack_pointer = (struct _object **) 0x818852c
        next_instr = (unsigned char *) 0x8191349 "\001n\001"
        opcode = 131
        oparg = 0
        why = WHY_NOT
        err = 0
        x = (struct _object *) 0x445c8a8c
        v = (struct _object *) 0x83
        w = (struct _object *) 0x4037a9f8
        u = (struct _object *) 0x818852c
        t = (struct _object *) 0x819120c
        stream = (struct _object *) 0x0
        fastlocals = (struct _object **) 0x8188528
        freevars = (struct _object **) 0x8188528
        retval = (struct _object *) 0x0
        tstate = (struct _ts *) 0x8132d28
        co = (struct {...} *) 0x4037c0e0
        instr_ub = -1
        instr_lb = 0
        first_instr = (unsigned char *) 0x819120c "d"
        names = (struct _object *) 0x402bf56c
        consts = (struct _object *) 0x402bd91c
#30 0x080a869c in PyEval_EvalCodeEx (co=0x4037c0e0, globals=0x1, locals=0x0, 
args=0x81883dc, argcount=0, kws=0x0, kwcount=0,    defs=0x0, defcount=0, 
closure=0x0) at Python/ceval.c:2640        f = (struct _frame *) 0x81883dc
        retval = (struct _object *) 0x0
        fastlocals = (struct _object **) 0x8188528
        freevars = (struct _object **) 0x8188528
        tstate = (struct _ts *) 0x8132d28
        x = (struct _object *) 0x1
        u = (struct _object *) 0x0
#31 0x080aae87 in PyEval_EvalCode (co=0x0, globals=0x0, locals=0x0) at 
Python/ceval.c:537No locals.
#32 0x080d1d4b in run_node (n=0x402b6428, filename=0x0, globals=0x0, 
locals=0x0, 
flags=0x0) at Python/pythonrun.c:1174        co = (struct {...} *) 0x4037c0e0
        v = (struct _object *) 0x402b6428
#33 0x080d1530 in PyRun_SimpleFileExFlags (fp=0x8132b78, filename=0xbffff791 
"./MyApp.py", closeit=1, flags=0xbffff598)    at Python/pythonrun.c:771
        m = (struct _object *) 0x0
        d = (struct _object *) 0x402cd79c
        v = (struct _object *) 0x1
        ext = 0x4037c0e0 "\002"
#34 0x08054be6 in Py_Main (argc=1, argv=0xbffff614) at Modules/main.c:415
        c = 0
        sts = 0
        command = 0x0
        filename = 0xbffff791 "./MyApp.py"
        fp = (struct _IO_FILE *) 0x8132b78
        p = 0x0
        inspect = 0
        unbuffered = 0
        skipfirstline = 0
        stdin_is_interactive = 1
        help = 0
        version = 0
        saw_inspect_flag = 0
        saw_unbuffered_flag = 0
        cf = {cf_flags = 0}
#35 0x0805476b in main (argc=0, argv=0x0) at Modules/python.c:23
No locals.
#36 0x4019adc4 in __libc_start_main () from /lib/libc.so.6
No symbol table info available.
(gdb)






More information about the PyQt mailing list