Issue 16676: Segfault under Python 3.3 after PyType_GenericNew (original) (raw)

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)) { PyErr_SetString(PyExc_TypeError, "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=, pp_stack=0x7fffffffa6e0) at Python/ceval.c:4064 #3 PyEval_EvalFrameEx (f=, throwflag=) at Python/ceval.c:2679 #4 0x0000000000480b23 in fast_function (nk=, na=1, n=, pp_stack=0x7fffffffa850, func=0x7ffff42284d0) at Python/ceval.c:4150 #5 call_function (oparg=, pp_stack=0x7fffffffa850) at Python/ceval.c:4083

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 type_object: PyObject_CallObject(type_object, NULL);