pl/python refcount bug

From: Neil Conway <neilc(at)samurai(dot)com>
To: pgsql-patches <pgsql-patches(at)postgresql(dot)org>
Subject: pl/python refcount bug
Date: 2006-01-09 18:07:30
Message-ID: 1136830050.8851.29.camel@localhost.localdomain
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-patches

In PLy_function_build_args(), the code loops repeatedly, constructing
one argument at a time and then inserting the argument into a Python
list via PyList_SetItem(). This "steals" the reference to the argument:
that is, the reference to the new list member is now held by the Python
list itself. This works fine, except if an elog occurs. This causes the
function's PG_CATCH() block to be invoked, which decrements the
reference counts on both the current argument and the list of arguments.
If the elog happens to occur during the second or subsequent iteration
of the loop, the reference count on the current argument will be
decremented twice.

The fix is simple: set the local pointer to the current argument to NULL
immediately after adding it to the argument list. This ensures that the
Py_XDECREF() in the PG_CATCH() block doesn't double-decrement. I'd like
to apply this to HEAD and back branches (as far back as PG_CATCH
exists).

The broader point is that the current approach to handling reference
counting and exceptions in PL/Python seems terribly error-prone. I
briefly skimmed the code for other instances of the problem -- while I
didn't find any, I don't have a lot of confidence that similar issues
don't exist. Any thoughts on how to improve that? (I wonder if we could
adapt ResOwner...)

-Neil

Attachment Content-Type Size
plpython_decref_fix-1.patch text/x-patch 376 bytes

Responses

Browse pgsql-patches by date

  From Date Subject
Next Message Tom Lane 2006-01-09 18:20:21 Re: [PATCHES] plpgsql: check domain constraints
Previous Message Yoshiyuki Asaba 2006-01-09 17:04:20 CREATEUSER == SUPERUSER?