4

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.

1 Answer 1

1

Ok, solved it. I needed to add Py_Initialize. New code that works:

int main() {
  printf("This is a dummy test\n");
  Py_Initialize();
  PyType_Ready(&MyObject_Type);
  printf("We did it\n");
  return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.