[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