[PyQt] Problems creating QApplication instance (backdoor in addTypeSlots)

Marcin Cieslak saper at saper.info
Wed Aug 4 16:11:46 BST 2010


Hello,

I am pretty new to Qt4 and SIP but I try to find a problem
with the startup of the Py-Qt4 application (Hewlett Packard
printer toolbox utility from hp-lip package) on my FreeBSD box.

My environment:

* FreeBSD 9.0-CURRENT #5 r206987: Tue Apr 27 20:45:03 CEST 2010
* Qt 4.6.3
* PyQt4 4.7.3 (configure options at the end of this email)
* SIP 4.10.2 (configure options at the end of this email)
* Python 2.5.5

Everything running on amd64 (64 bit), installed via FreeBSD
ports from source.

Simple "from PyQt4.QtGui import QApplication" fails with SIGSEGV:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 800e041c0 (LWP 100167)]
0x00000008057a666e in addTypeSlots (heap_to=0x8010c3020, slots=0x53)
     at siplib.c:9361
9361        while ((f = slots->psd_func) != NULL)
(gdb) bt
#0  0x00000008057a666e in addTypeSlots (heap_to=0x8010c3020, slots=0x53)
     at siplib.c:9361
#1  0x00000008057a790c in sipEnumType_alloc (self=0x8058acc20, nitems=0)
     at siplib.c:10496
#2  0x000000000044eeac in type_new ()
#3  0x0000000000446c8a in type_call ()
#4  0x0000000000414fef in PyObject_Call ()
#5  0x000000080579fca8 in createContainerType (cod=0x801c89508,
     td=0x801c894e0, bases=0x801082410, metatype=0x8058acc20,
     mod_dict=0x800fb1160, client=0x801b3d300) at siplib.c:5231
#6  0x00000008057a0059 in createClassType (client=0x801b3d300,
     ctd=0x801c894e0, mod_dict=0x800fb1160) at siplib.c:5350
#7  0x0000000805795ad1 in sip_api_init_module (client=0x801b3d300,
     mod_dict=0x800fb1160) at siplib.c:1381
#8  0x0000000801580db7 in initQtGui ()
    from /usr/local/lib/python2.5/site-packages/PyQt4/QtGui.so

I have poked around a bit and I have trouble understanding one thing
in siplib.c:

createContainerType() uses a "currentType" global variable to pass
the QApplication class description to the object being created by
Python. An "sip.enumtyp" Python object is being created and then
sipEnumType_alloc() attempts to use currentType to fill in the slots
of the object.  However, it assumes that the currentType passed is
a pointer to (sipEnumTypeDef), while in this case it is (sipClassTypeDef).
Segmentation violation occurs when attepting to use illegal value of
"etd_pyslots" as a pointer.

How is "currentType" supposed to work in case of metaclass initialization?

Below please find a full dump from the gdb session, commands
supplied to gdb on stdin are given at the beginning of
the script.  (gdb /usr/local/bin/python < commands)

--Marcin


Script started on Wed Aug  4 16:49:03 2010
set height 0
set args -c 'from PyQt4.QtGui import QApplication'
run
bt
frame 1
list siplib.c:10496
output *(sipClassTypeDef*)currentType
echo \n
output *(sipEnumTypeDef*)currentType
echo \n
output *(sipClassTypeDef*)currentType
echo \n
frame 5 
list siplib.c:5231
output currentType
echo \n
output *(sipClassTypeDef*)currentType
echo \n
list siplib.c:5231
pyo args
frame 6
pyo metatype
quit
y
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "amd64-marcel-freebsd"...(no debugging symbols found)...
(gdb) set height 0
(gdb) set args -c 'from PyQt4.QtGui import QApplication'
(gdb) run
Starting program: /usr/local/bin/python -c 'from PyQt4.QtGui import QApplication'
(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...[New LWP 100291]
(no debugging symbols found)...(no debugging symbols found)...[New Thread 800e041c0 (LWP 100291)]
(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 800e041c0 (LWP 100291)]
0x00000008057a666e in addTypeSlots (heap_to=0x8010c3020, slots=0x53)
     at siplib.c:9361
9361	    while ((f = slots->psd_func) != NULL)
(gdb) bt
#0  0x00000008057a666e in addTypeSlots (heap_to=0x8010c3020, slots=0x53)
     at siplib.c:9361
#1  0x00000008057a790c in sipEnumType_alloc (self=0x8058acc20, nitems=0)
     at siplib.c:10496
#2  0x000000000044eeac in type_new ()
#3  0x0000000000446c8a in type_call ()
#4  0x0000000000414fef in PyObject_Call ()
#5  0x000000080579fca8 in createContainerType (cod=0x801c89508,
     td=0x801c894e0, bases=0x801082410, metatype=0x8058acc20,
     mod_dict=0x800fb1160, client=0x801b3d300) at siplib.c:5231
#6  0x00000008057a0059 in createClassType (client=0x801b3d300,
     ctd=0x801c894e0, mod_dict=0x800fb1160) at siplib.c:5350
#7  0x0000000805795ad1 in sip_api_init_module (client=0x801b3d300,
     mod_dict=0x800fb1160) at siplib.c:1381
#8  0x0000000801580db7 in initQtGui ()
    from /usr/local/lib/python2.5/site-packages/PyQt4/QtGui.so
#9  0x000000000047b9a4 in _PyImport_LoadDynamicModule ()
#10 0x000000000047a006 in import_submodule ()
#11 0x000000000047a4bc in load_next ()
#12 0x000000000047a6ed in import_module_level ()
#13 0x000000000047aad4 in PyImport_ImportModuleLevel ()
#14 0x00000000004636d2 in builtin___import__ ()
#15 0x0000000000414fef in PyObject_Call ()
#16 0x0000000000463bca in PyEval_CallObjectWithKeywords ()
#17 0x0000000000466eee in PyEval_EvalFrameEx ()
#18 0x0000000000469eb7 in PyEval_EvalCodeEx ()
#19 0x0000000000469f64 in PyEval_EvalCode ()
#20 0x0000000000481b61 in run_mod ()
#21 0x0000000000481cdc in PyRun_StringFlags ()
#22 0x0000000000482d09 in PyRun_SimpleStringFlags ()
#23 0x0000000000411cc5 in Py_Main ()
#24 0x00000000004118ee in main ()
(gdb) frame 1
#1  0x00000008057a790c in sipEnumType_alloc (self=0x8058acc20, nitems=0)
     at siplib.c:10496
10496	        addTypeSlots(&py_type->super, psd);
(gdb) list siplib.c:10496
10491	    /*
10492	     * Initialise any slots.  This must be done here, after the type is
10493	     * allocated but before PyType_Ready() is called.
10494	     */
10495	    if ((psd = ((sipEnumTypeDef *)currentType)->etd_pyslots) != NULL)
10496	        addTypeSlots(&py_type->super, psd);
10497 
10498	    currentType = NULL;
10499 
10500	    return (PyObject *)py_type;
(gdb) output *(sipClassTypeDef*)currentType
{ctd_base = {td_version = -1, td_next_version = 0x0, td_module = 0x801b3d300,
     td_flags = 16, td_cname = 71112, u = {td_py_type = 0x8010c3020,
       td_wrapper_type = 0x8010c3020}}, ctd_container = {cod_name = 71112,
     cod_scope = {sc_type = 0, sc_module = 0, sc_flag = 1}, cod_nrmethods = 83,
     cod_methods = 0x801c89720, cod_nrenummembers = 6,
     cod_enummembers = 0x801c8a180, cod_nrvariables = 0, cod_variables = 0x0,
     cod_instances = {id_type = 0x0, id_voidp = 0x0, id_char = 0x0,
       id_string = 0x0, id_int = 0x0, id_long = 0x0, id_ulong = 0x0,
       id_llong = 0x0, id_ullong = 0x0, id_double = 0x0}},
   ctd_docstring = 0x801c89400 "\001QApplication(list-of-str)\nQApplication(list-of-str, bool)\nQApplication(list-of-str, QApplication.Type)\nQApplication(Display, int visual=0, int colormap=0)\nQApplication(Display, list-of-str, int visua"..., ctd_metatype = -1, ctd_supertype = -1, ctd_supers = 0x801c894dc,
   ctd_pyslots = 0x0, ctd_init = 0x8019c0db0 <init_QApplication>,
   ctd_traverse = 0, ctd_clear = 0, ctd_readbuffer = 0, ctd_writebuffer = 0,
   ctd_segcount = 0, ctd_charbuffer = 0,
   ctd_dealloc = 0x8019bfc60 <dealloc_QApplication>, ctd_assign = 0,
   ctd_array = 0, ctd_copy = 0,
   ctd_release = 0x8019bfb80 <release_QApplication>,
   ctd_cast = 0x8019bbe70 <cast_QApplication>, ctd_cto = 0,
   ctd_nsextender = 0x0, ctd_pickle = 0}(gdb) echo \n

(gdb) output *(sipEnumTypeDef*)currentType
{etd_base = {td_version = -1, td_next_version = 0x0, td_module = 0x801b3d300,
     td_flags = 16, td_cname = 71112, u = {td_py_type = 0x8010c3020,
       td_wrapper_type = 0x8010c3020}}, etd_name = 71112, etd_scope = 16777216,
   etd_pyslots = 0x53}(gdb) echo \n

(gdb) output *(sipClassTypeDef*)currentType
{ctd_base = {td_version = -1, td_next_version = 0x0, td_module = 0x801b3d300,
     td_flags = 16, td_cname = 71112, u = {td_py_type = 0x8010c3020,
       td_wrapper_type = 0x8010c3020}}, ctd_container = {cod_name = 71112,
     cod_scope = {sc_type = 0, sc_module = 0, sc_flag = 1}, cod_nrmethods = 83,
     cod_methods = 0x801c89720, cod_nrenummembers = 6,
     cod_enummembers = 0x801c8a180, cod_nrvariables = 0, cod_variables = 0x0,
     cod_instances = {id_type = 0x0, id_voidp = 0x0, id_char = 0x0,
       id_string = 0x0, id_int = 0x0, id_long = 0x0, id_ulong = 0x0,
       id_llong = 0x0, id_ullong = 0x0, id_double = 0x0}},
   ctd_docstring = 0x801c89400 "\001QApplication(list-of-str)\nQApplication(list-of-str, bool)\nQApplication(list-of-str, QApplication.Type)\nQApplication(Display, int visual=0, int colormap=0)\nQApplication(Display, list-of-str, int visua"..., ctd_metatype = -1, ctd_supertype = -1, ctd_supers = 0x801c894dc,
   ctd_pyslots = 0x0, ctd_init = 0x8019c0db0 <init_QApplication>,
   ctd_traverse = 0, ctd_clear = 0, ctd_readbuffer = 0, ctd_writebuffer = 0,
   ctd_segcount = 0, ctd_charbuffer = 0,
   ctd_dealloc = 0x8019bfc60 <dealloc_QApplication>, ctd_assign = 0,
   ctd_array = 0, ctd_copy = 0,
   ctd_release = 0x8019bfb80 <release_QApplication>,
   ctd_cast = 0x8019bbe70 <cast_QApplication>, ctd_cto = 0,
   ctd_nsextender = 0x0, ctd_pickle = 0}(gdb) echo \n

(gdb) frame 5 
#5  0x000000080579fca8 in createContainerType (cod=0x801c89508,
     td=0x801c894e0, bases=0x801082410, metatype=0x8058acc20,
     mod_dict=0x800fb1160, client=0x801b3d300) at siplib.c:5231
5231	    if ((py_type = PyObject_Call(metatype, args, NULL)) == NULL)
(gdb) list siplib.c:5231
5226	        goto relname;
5227 
5228	    /* Pass the type via the back door. */
5229	    currentType = td;
5230 
5231	    if ((py_type = PyObject_Call(metatype, args, NULL)) == NULL)
5232	        goto relargs;
5233 
5234	    /* Add the type to the "parent" dictionary. */
5235	    if (PyDict_SetItem(scope_dict, name, py_type) < 0)
(gdb) output currentType
(sipTypeDef *) 0x801c894e0(gdb) echo \n

(gdb) output *(sipClassTypeDef*)currentType
{ctd_base = {td_version = -1, td_next_version = 0x0, td_module = 0x801b3d300,
     td_flags = 16, td_cname = 71112, u = {td_py_type = 0x8010c3020,
       td_wrapper_type = 0x8010c3020}}, ctd_container = {cod_name = 71112,
     cod_scope = {sc_type = 0, sc_module = 0, sc_flag = 1}, cod_nrmethods = 83,
     cod_methods = 0x801c89720, cod_nrenummembers = 6,
     cod_enummembers = 0x801c8a180, cod_nrvariables = 0, cod_variables = 0x0,
     cod_instances = {id_type = 0x0, id_voidp = 0x0, id_char = 0x0,
       id_string = 0x0, id_int = 0x0, id_long = 0x0, id_ulong = 0x0,
       id_llong = 0x0, id_ullong = 0x0, id_double = 0x0}},
   ctd_docstring = 0x801c89400 "\001QApplication(list-of-str)\nQApplication(list-of-str, bool)\nQApplication(list-of-str, QApplication.Type)\nQApplication(Display, int visual=0, int colormap=0)\nQApplication(Display, list-of-str, int visua"..., ctd_metatype = -1, ctd_supertype = -1, ctd_supers = 0x801c894dc,
   ctd_pyslots = 0x0, ctd_init = 0x8019c0db0 <init_QApplication>,
   ctd_traverse = 0, ctd_clear = 0, ctd_readbuffer = 0, ctd_writebuffer = 0,
   ctd_segcount = 0, ctd_charbuffer = 0,
   ctd_dealloc = 0x8019bfc60 <dealloc_QApplication>, ctd_assign = 0,
   ctd_array = 0, ctd_copy = 0,
   ctd_release = 0x8019bfb80 <release_QApplication>,
   ctd_cast = 0x8019bbe70 <cast_QApplication>, ctd_cto = 0,
   ctd_nsextender = 0x0, ctd_pickle = 0}(gdb) echo \n

(gdb) list siplib.c:5231
5226	        goto relname;
5227 
5228	    /* Pass the type via the back door. */
5229	    currentType = td;
5230 
5231	    if ((py_type = PyObject_Call(metatype, args, NULL)) == NULL)
5232	        goto relargs;
5233 
5234	    /* Add the type to the "parent" dictionary. */
5235	    if (PyDict_SetItem(scope_dict, name, py_type) < 0)
(gdb) pyo args
object  : ('QApplication', (<class 'PyQt4.QtCore.Version'>,), {'__module__': 'PyQt4.QtGui'})
type    : tuple
refcount: 1
address : 0x80107e730
Cannot set lwp 100291 registers: Invalid argument

Cannot set lwp 100291 registers: Invalid argument

(gdb) frame 6
#6  0x000000080579fca8 in createContainerType (cod=0x801c89508,
     td=0x801c894e0, bases=0x801082410, metatype=0x8058acc20,
     mod_dict=0x800fb1160, client=0x801b3d300) at siplib.c:5231
5231	    if ((py_type = PyObject_Call(metatype, args, NULL)) == NULL)
(gdb) pyo metatype
object  : <type 'sip.enumtype'>
type    : type
refcount: 2
address : 0x8058acc20
$1 = 50
(gdb) quit
The program is running.  Exit anyway? (y or n) 
Script done on Wed Aug  4 16:49:04 2010

* PyQt4-Gui 4.7.3:

cd /usr/obj/usr/ports/x11-toolkits/py-qt4-gui/work/PyQt-x11-gpl-4.7.3 && /usr/bin/env PYQT4_COMPONENT="gui" PYTHON="/usr/local/bin/python2.5" MOC="/usr/local/bin/moc-qt4" UIC="/usr/local/bin/uic-qt4" CPPFLAGS=" " LIBS=""  QMAKE="/usr/local/bin/qmake-qt4" QMAKESPEC="/usr/local/share/qt4/mkspecs/freebsd-g++" QTDIR="/usr/local" SHELL=/bin/sh CONFIG_SHELL=/bin/sh /usr/local/bin/python2.5 configure.py -b /usr/local/bin -d /usr/local/lib/python2.5/site-packages -p /usr/local/lib/qt4/plugins -q /usr/local/bin/qmake-qt4 --confirm-license --enable QtGui --qsci-api --qsci-api-destdir=/usr/local/share/qt4/qsci --sipdir /usr/local/share/py-sip
Determining the layout of your Qt installation...
This is the GPL version of PyQt 4.7.3 (licensed under the GNU General Public
License) for Python 2.5.5 on freebsd9.
Checking to see if the QtGui module should be built...
Qt v4.6.3 free edition is being used.
SIP 4.10.2 is being used.
The Qt header files are in /usr/local/include/qt4.
The shared Qt libraries are in /usr/local/lib/qt4.
The Qt binaries are in /usr/local/bin.
The Qt mkspecs directory is in /usr/local/share/qt4.
These PyQt modules will be built: QtCore, QtGui.
The PyQt Python package will be installed in
/usr/local/lib/python2.5/site-packages.
PyQt is being built with generated docstrings.
The QScintilla API file will be installed in
/usr/local/share/qt4/qsci/api/python.
The PyQt .sip files will be installed in /usr/local/share/py-sip.

* SIP 4.10.2:

cd /usr/obj/usr/ports/devel/py-sip/work/sip-4.10.2 && /usr/local/bin/python2.5 configure.py -b /usr/local/bin -d /usr/local/lib/python2.5/site-packages -e /usr/local/include/python2.5 -v /usr/local/share/py-sip -u
This is SIP 4.10.2 for Python 2.5.5 on freebsd9.
The SIP code generator will be installed in /usr/local/bin.
The SIP module will be installed in /usr/local/lib/python2.5/site-packages.
The SIP header file will be installed in /usr/local/include/python2.5.
The default directory to install .sip files in is /usr/local/share/py-sip.
The platform/compiler configuration is freebsd-g++.



More information about the PyQt mailing list