PyObject_CallObject code dump after calling 4 times

grbgooglefan ganeshborse at gmail.com
Thu Jan 3 23:23:41 EST 2008


On Jan 3, 8:49 pm, grbgooglefan <ganeshbo... at gmail.com> wrote:
> On Jan 3, 8:02 pm, Phil Thompson <p... at riverbankcomputing.co.uk>
> wrote:
>
>
>
>
>
> > 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- Hide quoted text -
>
> > - Show quoted text -
>
> Thanks for all the responses.
> These help me.
> I could simulate this crash in my small test program & I think (I
> could be wrong also) it is because of extraneous Py_XDECREF of
> "PyObject *val" which I am using to convert variables to tuple.
> When I change the code to simple do like this, it works fine.
>             PyTuple_SetItem(pytuple,0,PyLong_FromLong(size));
>             PyTuple_SetItem(pytuple,1,PyLong_FromLong(maxvol));
>             PyTuple_SetItem(pytuple,2,PyFloat_FromDouble(adv));- Hide quoted text -
>
> - Show quoted text -

Now my new code looks like this.
Do you think this is correct way to handle ref counts? Do you forsee
any issues of memory leaks, etc. here?

//
================================================================================
      switch(ndtyp){
            case(INT_T):
                       //printf("PyInt_FromLong val %d, var %s
\n",inputVar.nionum,pEvalFunc->pExprVarsArray[nCtr].szVarName);
 
PyTuple_SetItem(pTuple,nCtr,PyInt_FromLong(inputVar.nionum));
                       break;
            case(LONG_T):
                       //printf("PyLong_FromLong val %ld, var %s
\n",inputVar.lionum,pEvalFunc->pExprVarsArray[nCtr].szVarName);
 
PyTuple_SetItem(pTuple,nCtr,PyLong_FromLong(inputVar.lionum));
                       break;
            case(FLOAT_T):
                       //printf("PyFloat_FromDouble val %f, var %s
\n",inputVar.fionum,pEvalFunc->pExprVarsArray[nCtr].szVarName);
 
PyTuple_SetItem(pTuple,nCtr,PyFloat_FromDouble(inputVar.fionum));
                       break;
            case(DOUBLE_T):
                       //printf("PyFloat_FromDouble val %f, var %s
\n",inputVar.dionum,pEvalFunc->pExprVarsArray[nCtr].szVarName);
 
PyTuple_SetItem(pTuple,nCtr,PyFloat_FromDouble(inputVar.dionum));
                       break;
            case(STRING_T):
                       //printf("PyString_FromString val %s, var %s
\n",inputVar.ioString,pEvalFunc->pExprVarsArray[nCtr].szVarName);
 
PyTuple_SetItem(pTuple,nCtr,PyString_FromString(inputVar.ioString));
                       break;
            default:
                       printf("Unknown data type [%d] for %s
\n",ndtyp,pEvalFunc->pExprVarsArray[nCtr].szVarName);
                       bUnknownDataType = true;
                       break;
      }
      if(bUnknownDataType){ // got an unknown data type for a variable
        ret = -1;
        break;
      }
   }
   // all variables are set, call Python function
   if(ret == 0){
     PyObject *pResult = PyObject_CallObject(pEvalFunc-
>pPyEvalFunction,pTuple);

     if(PyErr_Occurred()){
       ret = -1;
       printf("error occured in PyObject_CallObject\n");
       PyErr_Print();
     } else {
        char* plevel = NULL;
        if(NULL != (plevel = PyString_AsString(pResult))){
          ret = 0;
          strncpy(szEvalResult,plevel,strlen(plevel));
          printf("Final result %s\n",szEvalResult);
        } else {
            printf("PyObject_CallObject returned NULL\n");
            ret = -1;
        }
     }
     Py_XDECREF(pResult);
     Py_XDECREF(pTuple);
//
================================================================================



More information about the Python-list mailing list