PyObject_CallFunctionObjArgs segfaults

MRAB python at mrabarnett.plus.com
Thu Sep 29 20:33:54 EDT 2022


On 2022-09-30 01:02, MRAB wrote:
> On 2022-09-29 23:41, Jen Kris wrote:
>>
>> I just solved this C API problem, and I’m posting the answer to help 
>> anyone else who might need it.
>>
[snip]

What I like to do is write comments that state which variables hold a 
reference, followed by '+' if it's a new reference (incref'ed) and '?' 
if it could be null. '+?' means that it's probably a new reference but 
could be null. Once I know that it's not null, I can remove the '?', and 
once I've decref'ed it (if required) and no longer need it, I remobe it 
from the comment.

Clearing up references, as soon as they're not needed, helps to keep the 
number of current references more manageable.


int64_t Get_LibModules(int64_t * return_array) {
     PyObject * pName_random = PyUnicode_FromString("random");
     //> pName_random+?
     if (!pName_random) {
         PyErr_Print();
         return 1;
     }

     //> pName_random+
     PyObject * pMod_random = PyImport_Import(pName_random);
     //> pName_random+ pMod_random+?
     Py_DECREF(pName_random);
     //> pMod_random+?
     if (!pMod_random) {
         PyErr_Print();
         return 1;
     }

     //> pMod_random+
     PyObject * pAttr_seed = PyObject_GetAttrString(pMod_random, "seed");
     //> pMod_random+ pAttr_seed?
     if (!pAttr_seed) {
         Py_DECREF(pMod_random);
         PyErr_Print();
         return 1;
     }

     //> pMod_random+ pAttr_seed
     PyObject * pAttr_randrange = PyObject_GetAttrString(pMod_random, 
"randrange");
     //> pMod_random+ pAttr_seed pAttr_randrange?
     Py_DECREF(pMod_random);
     //> pAttr_seed pAttr_randrange?
     if (!pAttr_randrange) {
         PyErr_Print();
         return 1;
     }

     //> pAttr_seed pAttr_randrange
     return_array[0] = (int64_t)pAttr_seed;
     return_array[1] = (int64_t)pAttr_randrange;

     return 0;
}

int64_t C_API_2(PyObject * pAttr_seed, Py_ssize_t value_1) {
     PyObject * value_ptr = PyLong_FromLong(value_1);
     //> value_ptr+?
     if (!!value_ptr) {
         PyErr_Print();
         return 1;
     }

     //> value_ptr+
     PyObject * p_seed_calc = PyObject_CallFunctionObjArgs(pAttr_seed, 
value_ptr, NULL);
     //> value_ptr+ p_seed_calc+?
     Py_DECREF(value_ptr);
     //> p_seed_calc+?
     if (!p_seed_calc) {
         PyErr_Print();
         return 1;
     }

     //> p_seed_calc+
     Py_DECREF(p_seed_calc);
     return 0;
}

int64_t C_API_12(PyObject * pAttr_randrange, Py_ssize_t value_1) {
     PyObject * value_ptr = PyLong_FromLong(value_1);
     //> value_ptr+?
     if (!value_ptr) {
         PyErr_Print();
         return 1;
     }

     //> value_ptr+
     PyObject * p_randrange_calc = 
PyObject_CallFunctionObjArgs(pAttr_randrange, value_ptr, NULL);
     //> value_ptr+ p_randrange_calc+?
     Py_DECREF(value_ptr);
     //> p_randrange_calc+?
     if (!p_randrange_calc) {
         PyErr_Print();
         return 1;
     }

     //Prepare return values
     //> p_randrange_calc+
     return_val = PyLong_AsLong(p_randrange_calc);
     Py_DECREF(p_randrange_calc);

     return return_val;
}



More information about the Python-list mailing list