[omniORB-dev] [omniORBPy] [Bug] Not clearing Python error state after method invocation

Moriarty predator777 at gmail.com
Thu Oct 2 18:52:00 BST 2008


Hi!

Another bug in omniORBPy. Steps to reproduce:
  1) make simple servant with two methods: foo() with body
"time.sleep(0.1); assert(False)", and boo() with body
"time.sleep(0.2); return 'Ok'"
  2) remotely call servant's foo() method. You would catch Unknown
Python exception, it's ok.
  3) remotely call servant's boo() method. You would catch Unknown
Python exception too, it's error.

In real world, it causes our "good" methods, that normally never
throw, to raise Unknown python exceptions. Traceback is something
strange:
  File "/usr/lib/bla/utils.py", line 153, in protected
    return func (*args, **kw)
  File "/usr/lib/bla/utils.py", line 257, in new_fun
    start_resources = resource.getrusage(resource.RUSAGE_SELF)
AttributeError: 'exceptions.AssertionError' object has no attribute
'_NP_RepositoryId'


The problem is:
------- (modules/pyServant.cc and 4 places more)
    PyObject *etype, *evalue, *etraceback;
    PyObject *erepoId = 0;
    PyErr_Fetch(&etype, &evalue, &etraceback);
    PyErr_NormalizeException(&etype, &evalue, &etraceback);
    OMNIORB_ASSERT(etype);

    if (evalue)
      erepoId = PyObject_GetAttrString(evalue, (char*)"_NP_RepositoryId");

    if (!(erepoId && PyString_Check(erepoId))) {
      //(1)
      Py_XDECREF(erepoId);
      if (omniORB::trace(1)) {
        {
          omniORB::logger l;
          l << "Caught an unexpected Python exception during up-call.\n";
        }
        PyErr_Restore(etype, evalue, etraceback);
        PyErr_Print();
      }
      else {
	Py_DECREF(etype); Py_XDECREF(evalue); Py_XDECREF(etraceback);
      }
      OMNIORB_THROW(UNKNOWN, UNKNOWN_PythonException, CORBA::COMPLETED_MAYBE);
    }
-------

In (1), after calling PyObject_GetAttrString for object without
"_NP_RepositoryId" attribute, python error state is set. It can be
avoided by 3 alternatives, at least:
 1) simply set threadLevel = 1 (PyErr_Print will clear error state) :)
 2) Just add PyErr_Clear() in (1). Do not forget to do it in 5 places :)
 3) Check && apply attached patch. It reduce copy-paste and insert
PyErr_Clear() in one right place. I'm unsure about it's ideological
correctness, so, review it, please.

-- 
With best wishes && regards, Morarenko Kirill
-------------- next part --------------
A non-text attachment was scrubbed...
Name: modules.diff
Type: application/octet-stream
Size: 11997 bytes
Desc: not available
Url : http://www.omniorb-support.com/pipermail/omniorb-dev/attachments/20081002/05dc1705/modules.obj


More information about the omniORB-dev mailing list