[pygtk] Apparent PyGTK Segmentation Fault

Casey McGinty casey.mcginty at gmail.com
Sat Aug 23 18:16:57 WST 2008


I have more details on this failure starting with a Valgrind backtrace that
matches the previous segfault backtrace stack.

==19113== Invalid read of size 4
==19113==    at 0x4926B80: _wrap_gtk_menu_popup (gtk.override:1554)
==19113==    by 0x80C9AB2: PyEval_EvalFrameEx (ceval.c:3573)
==19113==    by 0x80CB1F6: PyEval_EvalCodeEx (ceval.c:2836)
==19113==    by 0x811372D: function_call (funcobject.c:517)
==19113==    by 0x805CB96: PyObject_Call (abstract.c:1861)
==19113==    by 0x8062BFA: instancemethod_call (classobject.c:2519)
==19113==    by 0x805CB96: PyObject_Call (abstract.c:1861)
==19113==    by 0x80C2E9B: PyEval_CallObjectWithKeywords (ceval.c:3442)
==19113==    by 0x805D03F: PyObject_CallObject (abstract.c:1852)
==19113==    by 0x4819AFA: pyg_closure_marshal (pygtype.c:1129)
==19113==    by 0x4789758: g_closure_invoke (gclosure.c:490)
==19113==    by 0x479DF8A: signal_emit_unlocked_R (gsignal.c:2440)
==19113==  *Address 0x6c is not stack'd, malloc'd or (recently) free'd*
==19113==
==19113== Process terminating with default action of signal 11 (SIGSEGV)
==19113==  Access not within mapped region at address 0x6C

The function _wrap_gtk_menu_popup fails at the following code block:

    /* this is an ugly hack to avoid leaking memory and references
       gtk_menu_popup should use a data destroy function */
    if (menu->position_func == pygtk_menu_position) {    <------ FAILURE
'menu' is 0x6C
        cunote = menu->position_func_data;
        Py_DECREF(cunote->func);
        Py_XDECREF(cunote->data);
        g_free(cunote);
    }

Setting a breakpoint at the start of the function _wrap_gtk_menu_popup .....

Breakpoint 2, _wrap_gtk_menu_popup (self=0xb6cf72ac, args=0xb6f815fc,
kwargs=0x0)
    at /build/buildd/pygtk-2.12.1/gtk/gtk.override:1510
*1510        GtkMenu *menu = GTK_MENU(self->obj);*
(gdb) print self
$1 = (PyGObject *) 0xb6cf72ac
(gdb) print *self
$2 = {ob_refcnt = 5, ob_type = 0xb7aa7220, obj = 0x0, inst_dict = 0x0,
weakreflist = 0x0, private_flags = {
    closures = 0x0, flags = 0}}
(gdb) print *self->ob_type
$3 = {ob_refcnt = 30, ob_type = 0x81f900c, ob_size = 0, tp_name = 0xb7a80cdc
"gtk.Menu",
  tp_basicsize = 24, tp_itemsize = 0, tp_dealloc = 0xb7ad15c0
<pygobject_dealloc>, tp_print = 0,
  tp_getattr = 0, tp_setattr = 0, tp_compare = 0xb7acce20
<pygobject_compare>,
  tp_repr = 0xb7acf5f0 <pygobject_repr>, tp_as_number = 0xb7ab0f20,
tp_as_sequence = 0xb7ab0fc0,
  tp_as_mapping = 0x0, tp_hash = 0xb7acce40 <pygobject_hash>, tp_call = 0,
  tp_str = 0x809ad00 <object_str>, tp_getattro = 0x8089670
<PyObject_GenericGetAttr>,
  tp_setattro = 0xb7ad1700 <pygobject_setattro>, tp_as_buffer = 0x0,
tp_flags = 153067, tp_doc = 0x0,
  tp_traverse = 0xb7ad14b0 <pygobject_traverse>, tp_clear = 0xb7acf540
<pygobject_clear>,
  tp_richcompare = 0, tp_weaklistoffset = 16, tp_iter = 0xb7a2d430
<_wrap_gtk_container_tp_iter>,
  tp_iternext = 0, tp_methods = 0xb7a960e0, tp_members = 0x0, tp_getset =
0x0, tp_base = 0xb7aa7160,
  tp_dict = 0xb70092d4, tp_descr_get = 0, tp_descr_set = 0, tp_dictoffset =
12,
  tp_init = 0xb7939100 <_wrap_gtk_menu_new>, tp_alloc = 0x809bd30
<PyType_GenericAlloc>,
  tp_new = 0x809aa60 <PyType_GenericNew>, tp_free = 0xb7acf1a0
<pygobject_free>, tp_is_gc = 0,
  tp_bases = 0xb700ae2c, tp_mro = 0xb700246c, tp_cache = 0x0, tp_subclasses
= 0xb70228ac,
  tp_weaklist = 0xb7008acc, tp_del = 0}
*(gdb) print self->obj
$4 = (GObject *) 0x0*

Does anyone know if self->obj should ever be NULL since it is never checked
in this function?

Here is a sample of the system when this function call passes correctly.
Obviously in this case self->obj references a valid (GObject*).

Breakpoint 2, _wrap_gtk_menu_popup (self=0xb6cdf2fc, args=0xb6f675fc,
kwargs=0x0)
    at /build/buildd/pygtk-2.12.1/gtk/gtk.override:1510
1510        GtkMenu *menu = GTK_MENU(self->obj);
(gdb) print self
$1 = (PyGObject *) 0xb6cdf2fc
(gdb) print *self
$2 = {ob_refcnt = 5, ob_type = 0xb7a8d220, obj = 0x83d8478, inst_dict = 0x0,
weakreflist = 0x0,
  private_flags = {closures = 0x0, flags = 0}}
(gdb) print *self->ob_type
$3 = {ob_refcnt = 31, ob_type = 0x81f900c, ob_size = 0, tp_name = 0xb7a66cdc
"gtk.Menu",
  tp_basicsize = 24, tp_itemsize = 0, tp_dealloc = 0xb7ab75c0
<pygobject_dealloc>, tp_print = 0,
  tp_getattr = 0, tp_setattr = 0, tp_compare = 0xb7ab2e20
<pygobject_compare>,
  tp_repr = 0xb7ab55f0 <pygobject_repr>, tp_as_number = 0xb7a96f20,
tp_as_sequence = 0xb7a96fc0,
  tp_as_mapping = 0x0, tp_hash = 0xb7ab2e40 <pygobject_hash>, tp_call = 0,
  tp_str = 0x809ad00 <object_str>, tp_getattro = 0x8089670
<PyObject_GenericGetAttr>,
  tp_setattro = 0xb7ab7700 <pygobject_setattro>, tp_as_buffer = 0x0,
tp_flags = 153067, tp_doc = 0x0,
  tp_traverse = 0xb7ab74b0 <pygobject_traverse>, tp_clear = 0xb7ab5540
<pygobject_clear>,
  tp_richcompare = 0, tp_weaklistoffset = 16, tp_iter = 0xb7a13430
<_wrap_gtk_container_tp_iter>,
  tp_iternext = 0, tp_methods = 0xb7a7c0e0, tp_members = 0x0, tp_getset =
0x0, tp_base = 0xb7a8d160,
  tp_dict = 0xb6fef2d4, tp_descr_get = 0, tp_descr_set = 0, tp_dictoffset =
12,
  tp_init = 0xb791f100 <_wrap_gtk_menu_new>, tp_alloc = 0x809bd30
<PyType_GenericAlloc>,
  tp_new = 0x809aa60 <PyType_GenericNew>, tp_free = 0xb7ab51a0
<pygobject_free>, tp_is_gc = 0,
  tp_bases = 0xb6ff0e2c, tp_mro = 0xb6fe846c, tp_cache = 0x0, tp_subclasses
= 0xb70088ac,
  tp_weaklist = 0xb6feeacc, tp_del = 0}
(gdb) print self->obj
$4 = (GObject *) 0x83d8478
(gdb) print *self->obj
$5 = {g_type_instance = {g_class = 0x8354c00}, ref_count = 1, qdata =
0x8387a00}

- Casey
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.daa.com.au/pipermail/pygtk/attachments/20080823/8e5a1659/attachment.htm 


More information about the pygtk mailing list