I have an application that starts in C++ and calls into Python that I'm converting to Python 3. I'm getting a segmentation fault in PyType_Ready that I do not get on python 2.
Here are the steps to reproduce on CENTOS 7, gcc 4.8.5, using conda to get py2/py3:
cd $WORKING # new empty directory
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh # use $WORKING/mc3 for the prefix
source mc3/etc/profile.d/conda.sh
conda create -n py2 python=2
conda create -n py3 python=3
conda activate py2
export LD_LIBRARY_PATH=$CONDA_PREFIX/lib
g++ -o dummy_py2 -I$CONDA_PREFIX/include/python2.7 -L$CONDA_PREFIX/lib -lpython2.7 dummy.cpp
./dummy_py2 # this runs ok
conda deactivate
conda activate py3
export LD_LIBRARY_PATH=$CONDA_PREFIX/lib
g++ -o dummy_py3 -I$CONDA_PREFIX/include/python3.8 -L$CONDA_PREFIX/lib -lpython3.8 dummy.cpp
./dummy_py3 # seg fault
Where dummy.cpp is:
#define PY_SSIZE_T_CLEAN
#include "Python.h"
typedef struct {
PyObject_HEAD
const char *data;
} MyObject;
static PyTypeObject MyObject_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"mymod.MyObject", /* tp_name */
sizeof(MyObject), /* tp_basicsize */
0, /* tp_itemsize */
};
int main() {
printf("This is a dummy test\n");
PyType_Ready(&MyObject_Type);
printf("We did it\n");
return 0;
}
I've used gdb to get the stack trace (edited for paths):
#0 0x00007f6966929b62 in PyTuple_New () from $CONDA_PREFIX/lib/libpython3.8.so.1.0
#1 0x00007f696692bb46 in PyType_Ready () from $CONDA_PREFIX/lib/libpython3.8.so.1.0
#2 0x00007f696692ca27 in PyType_Ready () from $CONDA_PREFIX/lib/libpython3.8.so.1.0
#3 0x00000000004006b5 in main ()
Relevant reference (I'm using the Examples section): https://docs.python.org/3/c-api/typeobj.html
I've tried to create this minimal example from a much bigger application but hopefully this is a supported use case? Thanks for any help.