[ZODB-Dev] Latest news: core dump with small change to POSException.py
Greg Ward
gward@mems-exchange.org
Thu, 4 Oct 2001 14:17:08 -0400
On 26 September 2001, I said:
> Is this as simple as recursively grep'ing for "ConflictError" in
> StandaloneZODB/.../*.c, and inspecting the code found in the
> neighbourhood of that identifier being used? If so, I'll take a crack
> at it -- looks like it only happens in a handful of places.
OK, I've started looking into how ConflictError is raised in the ZODB C
code. It looks like it's only done in three source files:
BTrees/BTreeTemplate.c
BTrees/BucketTemplate.c
BTrees/MergeTemplate.c
...and it's only done in one place in each of those files. Good.
BTreeTemplate.c does this, in BTree__p_resolveConflict
err:
if (r) {
ASSIGN(r, Py_BuildValue("((O))", r));
} else {
PyObject *error;
PyObject *value;
PyObject *traceback;
/* Change any errors to ConflictErrors */
/* XXX need to change this -GW */
PyErr_Fetch(&error, &value, &traceback);
Py_INCREF(ConflictError);
Py_XDECREF(error);
PyErr_Restore(ConflictError, value, traceback);
}
>From reading the Python C API manual, I believe the "else" clause is the
moral equivalent of this:
except:
(error, value, traceback) = sys.excinfo()
raise ConflictError, value, traceback
...which seems like a rather strange thing to me, but what do I know?
Anyways, this is problematic because the ConflictError constructor gets
involved, and I have changed that constructor's signature from the
default Exception constructor:
def __init__ (self, *args)
to
def __init__ (self [, message [, object [, serials]]])
and passing some arbitrary exception object to this cause a TypeError.
(The coredump in testConflict.py has been worked around by qualifying an
unqualified "except".)
I'm not sure of the best way to fix this. The most obvious is to do the
C equivalent of this:
except:
(error, value, traceback) = sys.excinfo()
raise ConflictError(str(value)), traceback
-- ie. don't pass an arbitrary exception object to the ConflictError
constructor, instead use its stringification as the ConflictError's
message.
It'll take me a while to learn how to do this in C, but I'm sure it
won't be too hard. But before I do, does this sound like the right way
to fix this code?
(BTW, the ConflictError raise in BucketTemplate.c is quite similar to
this one, so the same solution should apply. I haven't figured out what
to do about the one in MergeTemplate.c yet.)
Greg
--
Greg Ward - software developer gward@mems-exchange.org
MEMS Exchange http://www.mems-exchange.org