Title: Segfault under Python 3.3 after PyType_GenericNew
Type: Stage:
Components: Extension Modules, Interpreter Core Versions: Python 3.3
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: Arfrever, Mark.Shannon, jcea, tseaver
Priority: normal Keywords:

Created on 2012-12-14 02:31 by tseaver, last changed 2013-03-28 00:11 by benjamin.peterson. This issue is now closed.

Messages (2)
msg177441 - (view) Author: Tres Seaver (tseaver) * Date: 2012-12-14 02:31
A test of the 'persistent' package C extension segfaults under 3.3,
but completes successfully under 3.2.  The C function being tested
is a wrapper around PyType_GenericNew:

static PyObject *
simple_new(PyObject *self, PyObject *type_object)
    if (!PyType_Check(type_object))
                        "simple_new argument must be a type object.");
        return NULL;
    return PyType_GenericNew((PyTypeObject *)type_object, NULL, NULL);

The unit test which segfaults just iterates over basic types:

        def test_w_type(self):
            for typ in (type, list, dict, tuple, object):
                self.assertTrue(isinstance(self._callFUT(typ), typ))

Some digging shows that the segfault comes while deallocating the
newly-made 'dict' object.

#0  dict_dealloc (mp=0x7ffff3f9d248) at Objects/dictobject.c:1392
#1  0x00000000004261cb in tupledealloc (op=0x7ffff3d90ab8)
    at Objects/tupleobject.c:238
#2  0x000000000048065d in call_function (oparg=<optimized out>, 
    pp_stack=0x7fffffffa6e0) at Python/ceval.c:4064
#3  PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:2679
#4  0x0000000000480b23 in fast_function (nk=<optimized out>, na=1, 
    n=<optimized out>, pp_stack=0x7fffffffa850, func=0x7ffff42284d0)
    at Python/ceval.c:4150
#5  call_function (oparg=<optimized out>, pp_stack=0x7fffffffa850)
    at Python/ceval.c:4083
msg185387 - (view) Author: Mark Shannon (Mark.Shannon) * (Python committer) Date: 2013-03-27 23:07
This issue should be considered closed.

PyType_GenericNew is a convenience function for typeobjects to put in their tp_new slots. Calling it directly only works for some types. 
It worked in 3.2 for dict, but that was happenstance.

You could use 
((PyTypeObject *)type_object)->tp_new((PyTypeObject *)type_object, NULL, NULL);
to call the new method directly, but it would be better to call the 
PyObject_CallObject(type_object, NULL);
Date User Action Args
2013-03-28 00:11:49benjamin.petersonsetstatus: open -> closed
resolution: not a bug
2013-03-27 23:07:57Mark.Shannonsetmessages: + msg185387
2012-12-14 17:17:00Mark.Shannonsetnosy: + Mark.Shannon
2012-12-14 11:46:40jceasetnosy: + jcea
2012-12-14 08:20:31Arfreversetnosy: + Arfrever
2012-12-14 02:31:02tseavercreate