PyObject_CallObject code dump after calling 4 times

Phil Thompson phil at riverbankcomputing.co.uk
Thu Jan 3 07:02:00 EST 2008


On Thursday 03 January 2008, grbgooglefan wrote:
> I have a following C++ code which uses PyObject_CallObject to evaluate
> expressions dynamically. This code sets the input parameters for the
> function also dynamically. After calling this function 4 times (with
> these shown values), PyObject_CallObject  causes application to crash
> in frame_dealloc.
> 1) Can some one please help me understand why is this crash happening
> in frame_dealloc & how to solve it?
> 2) Is there anything wrong I am doing about incrementing or
> decrementing the reference counts of the object passed to
> PyObject_CallObject?

Yes.

> 3) Is it because of the big value (2299265.500000) I am trying to
> convert from double to float using PyFloat_FromDouble?
>
> //========================= code reduced for readability
> ===============
> switch(ndtyp){
>      case(INT_T):
>          {
>          printf("PyInt_FromLong val %d, var %s
> \n",inputVar.nionum,pEvalFunc->pExprVarsArray[nCtr].szVarName);
>          val = PyInt_FromLong(inputVar.nionum);
>          break;
>          }
>       case(LONG_T):
>          {
>          printf("PyLong_FromLong val %ld, var %s
> \n",inputVar.lionum,pEvalFunc->pExprVarsArray[nCtr].szVarName);
>          val = PyLong_FromLong(inputVar.lionum);
>          break;
>          }
>       case(FLOAT_T):
>          {
>          printf("PyFloat_FromDouble val %f, var %s
> \n",inputVar.fionum,pEvalFunc->pExprVarsArray[nCtr].szVarName);
>          val = PyFloat_FromDouble(inputVar.fionum);
>          break;
>          }
>       case(DOUBLE_T):
>          {
>          printf("PyFloat_FromDouble val %f, var %s
> \n",inputVar.dionum,pEvalFunc->pExprVarsArray[nCtr].szVarName);
>          val = PyFloat_FromDouble(inputVar.dionum);
>          break;
>          }
>        case(STRING_T):
>          {
>          printf("PyString_FromString val %s, var %s
> \n",inputVar.ioString,pEvalFunc->pExprVarsArray[nCtr].szVarName);
>          val = PyString_FromString(inputVar.ioString);
>          break;
>          }
>        default:
>          printf("Unknown data type [%d] for %s\n",ndtyp,pEvalFunc-
>
> >pExprVarsArray[nCtr].szVarName);
>
> }
> if(!val){
>    ret = -1;
>    printf("Failed to convert %d %s to PyObject\n",ndtyp,pEvalFunc-
>
> >pExprVarsArray[nCtr].szVarName); fflush(stdout);
>
>    Py_XDECREF(pTuple);
>    break;
> }
>   PyTuple_SetItem(pTuple, nCtr, val);
>   Py_XDECREF(val);

Don't do this - PyTuple_SetItem() steals a reference to val.

> }
> // all variables are set, call Python function
> Py_XINCREF(pTuple);

Why do this?

>   PyObject *pResult = PyObject_CallObject(pEvalFunc-
>
> >pPyEvalFunction,pTuple);
>
> Py_XDECREF(pTuple);

Why do this?

> if(PyErr_Occurred()){
>  PyErr_Print();
> } else {
>       char* plevel = NULL;
>       if(NULL != (plevel = PyString_AsString(pResult))){
>         ret = 0;
>         sprintf(szEvalResult,"%s",plevel);
>       }
> }
> Py_XDECREF(pResult);

pTuple will now have the same number of references as when you started the 
above code, so you may want to Py_DECREF() it.

Phil



More information about the Python-list mailing list