Skip to content

sigsegv on exit for static PyObject Py_XDECREF #126508

@ovesh

Description

@ovesh

Bug report

Bug description:

Noticed that on py312 a C extension I maintain is segfaulting when python exits. Managed to create a minimal C extension that reproduces the issue:

#include <Python.h>
#include <memory>

struct PyObjectDecrementer {
	void operator()(PyObject* obj) const {
		Py_XDECREF(obj);
	};
};

static std::unique_ptr<PyObject, PyObjectDecrementer> stored_obj = nullptr;

static PyObject* set_stored_int(PyObject* self, PyObject* args) {
    const int* input_int;

    if (!PyArg_ParseTuple(args, "i", &input_int)) {
        printf("failed to parse input int\n");
        return NULL;
    }

    PyObject* new_int = PyLong_FromLong((long)input_int);
    if (!new_int) {
        printf("failed to create new int object\n");
        return NULL;
    }

    stored_obj.reset(new_int);

    Py_RETURN_NONE;
}

static PyMethodDef HelloMethods[] = {
    {"set_stored_int", set_stored_int, METH_VARARGS, "Store a Python int in a static variable."},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef hellomodule = {
    PyModuleDef_HEAD_INIT, "hello", NULL, -1, HelloMethods
};

PyMODINIT_FUNC PyInit_hello(void) {
    return PyModule_Create(&hellomodule);
}

Minimal setup.py:

from setuptools import setup, Extension
hello_module = Extension('hello', sources=['library.cpp'])
setup(name='hello', version='1.0', description='xxxyyy', ext_modules=[hello_module])
% python
Python 3.12.7 | packaged by conda-forge | (main, Oct  4 2024, 15:55:29) [Clang 17.0.6 ] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import hello
>>> hello.set_stored_int(23)
>>> exit()
zsh: segmentation fault  python

Occurs at least on linux amd64 and MacOS. Narrowed it down with git bisect to this commit: df3173d

CPython versions tested on:

3.12

Operating systems tested on:

Linux, macOS

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions