PyObject_CallFunctionObjArgs segfaults
MRAB
python at mrabarnett.plus.com
Thu Sep 29 13:06:49 EDT 2022
On 2022-09-29 16:54, Jen Kris via Python-list wrote:
> Recently I completed a project where I used PyObject_CallFunctionObjArgs extensively with the NLTK library from a program written in NASM, with no problems. Now I am on a new project where I call the Python random library. I use the same setup as before, but I am getting a segfault with random.seed.
>
> At the start of the NASM program I call a C API program that gets PyObject pointers to “seed” and “randrange” in the same way as I did before:
>
> int64_t Get_LibModules(int64_t * return_array)
> {
> PyObject * pName_random = PyUnicode_FromString("random");
> PyObject * pMod_random = PyImport_Import(pName_random);
>
Both PyUnicode_FromString and PyImport_Import return new references or
null pointers.
> if (pMod_random == 0x0){
> PyErr_Print();
You're leaking a reference here (pName_random).
> return 1;}
>
> PyObject * pAttr_seed = PyObject_GetAttrString(pMod_random, "seed");
> PyObject * pAttr_randrange = PyObject_GetAttrString(pMod_random, "randrange");
>
> return_array[0] = (int64_t)pAttr_seed;
> return_array[1] = (int64_t)pAttr_randrange;
>
You're leaking 2 references here (pName_random and pMod_random).
> return 0;
> }
>
> Later in the same program I call a C API program to call random.seed:
>
> int64_t C_API_2(PyObject * pAttr_seed, Py_ssize_t value_1)
> {
> PyObject * p_seed_calc = PyObject_CallFunctionObjArgs(pAttr_seed, value_1);
It's expecting all of the arguments to be PyObject*, but value_1 is
Py_ssize_t instead of PyObject* (a pointer to a _Python_ int).
The argument list must end with a null pointer.
It returns a new reference or a null pointer.
>
> if (p_seed_calc == 0x0){
> PyErr_Print();
> return 1;}
>
> //Prepare return values
> long return_val = PyLong_AsLong(p_seed_calc);
>
You're leaking a reference here (p_seed_calc).
> return return_val;
> }
>
> The first program correctly imports “random” and gets pointers to “seed” and “randrange.” I verified that the same pointer is correctly passed into C_API_2, and the seed value (1234) is passed as Py_ssize_t value_1. But I get this segfault:
>
> Program received signal SIGSEGV, Segmentation fault.
> 0x00007ffff64858d5 in _Py_INCREF (op=0x4d2) at ../Include/object.h:459
> 459 ../Include/object.h: No such file or directory.
>
> So I tried Py_INCREF in the first program:
>
> Py_INCREF(pMod_random);
> Py_INCREF(pAttr_seed);
>
> Then I moved Py_INCREF(pAttr_seed) to the second program. Same segfault.
>
> Finally, I initialized “random” and “seed” in the second program, where they are used. Same segfault.
>
> The segfault refers to Py_INCREF, so this seems to do with reference counting, but Py_INCREF didn’t solve it.
>
> I’m using Python 3.8 on Ubuntu.
>
> Thanks for any ideas on how to solve this.
>
> Jen
>
More information about the Python-list
mailing list