[Python-Dev] Crash in new "trashcan" mechanism.

Vladimir Marangozov Vladimir.Marangozov@inrialpes.fr
Wed, 12 Apr 2000 05:18:26 +0200 (CEST)


Christian Tismer wrote:
>
> Vladimir Marangozov wrote:
> > 
> > Not enough good reasons to segfault. I suggest you move the
> > call to _PyTrash_deposit_object in TRASHCAN_BEGIN and invert
> > the condition there.
> 
> Sorry, I don't see what you are suggesting, I'm distracted.

I was thinking about the following. Change the macros in object.h from:

#define Py_TRASHCAN_SAFE_BEGIN(op) \
        { \
                ++_PyTrash_delete_nesting; \
                if (_PyTrash_delete_nesting < PyTrash_UNWIND_LEVEL) { \

#define Py_TRASHCAN_SAFE_END(op) \
                ;} \
                else \
                        _PyTrash_deposit_object((PyObject*)op);\
                --_PyTrash_delete_nesting; \
                if (_PyTrash_delete_later && _PyTrash_delete_nesting <= 0) \
                        _PyTrash_destroy_list(); \
        } \

to:

#define Py_TRASHCAN_SAFE_BEGIN(op) \
        { \
                ++_PyTrash_delete_nesting; \
                if (_PyTrash_delete_nesting >= PyTrash_UNWIND_LEVEL && \
                    _PyTrash_deposit_object((PyObject*)op) != 0) {    \

#define Py_TRASHCAN_SAFE_END(op) \
                ;} \
                --_PyTrash_delete_nesting; \
                if (_PyTrash_delete_later && _PyTrash_delete_nesting <= 0) \
                        _PyTrash_destroy_list(); \
        } \

where _PyTrash_deposit_object returns 0 on success, -1 on failure. This
gives another last chance to the system to finalize the object, hoping
that the stack won't overflow. :-)

My point is that it is better to control whether _PyTrash_deposit_object
succeeds or not (and it may fail because of PyList_Append).

If this doesn't sound acceptable (because of the possible stack overflow)
it would still be better to abort in _PyTrash_deposit_object with an
exception "stack overflow on recursive finalization" when PyList_Append
fails. Leaving it unchecked is not nice -- especially in such extreme
situations.

Currently, if something fails, the object is not finalized (leaking
memory). Ok, so be it. What's not nice is that this happens silently
which is not the kind of tolerance I would accept from the Python runtime.

As to the bug: it's curious that, as Mark reported, without the trashcan
logic, things seem to run fine. The trashcan seems to provoke (ok, detect ;)
some erroneous situation. I'd expect that if the trashcan macros are
implemented as above, the crash will go away (which wouldn't solve the
problem and would obviate the trashcan in the first place :-)

-- 
       Vladimir MARANGOZOV          | Vladimir.Marangozov@inrialpes.fr
http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252