Re: fix crash with Python 3.11

From: Peter Eisentraut <peter(dot)eisentraut(at)enterprisedb(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: fix crash with Python 3.11
Date: 2022-02-01 14:24:53
Message-ID: bd4dd309-c889-c20c-6be8-a3943cd94882@enterprisedb.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 25.01.22 16:54, Tom Lane wrote:
> Peter Eisentraut <peter(dot)eisentraut(at)enterprisedb(dot)com> writes:
>> On 16.01.22 23:53, Tom Lane wrote:
>>> I think a possible fix is:
>>>
>>> 1. Before entering the PG_TRY block, check for active subtransaction(s)
>>> and immediately throw a Python error if there is one. (This corresponds
>>> to the existing errors "cannot commit while a subtransaction is active"
>>> and "cannot roll back while a subtransaction is active". The point is
>>> to reduce the number of system states we have to worry about below.)
>
>> AFAICT, AbortOutOfAnyTransaction() also aborts subtransactions, so why
>> do you suggest the separate handling of subtransactions?
>
> We don't want these operations to be able to cancel subtransactions,
> do we? The existing errors certainly suggest not.

I've been struggling to make progress on this. First, throwing the
Python exception suggested in #1 above would require a significant
amount of new code. (We have code to create an exception out of
ErrorData, but no code to make one up from nothing.) This would need
further thought on how to arrange the code sensibly. Second, calling
AbortOutOfAnyTransaction() appears to clean up so much stuff that even
the data needed for error handling in PL/Python is wiped out. The
symptoms are various crashes on pointers now valued 0x7f7f7f... You fix
one, you get the next one. So more analysis would be required there, too.

One way to way to address the first problem is to not handle the "cannot
commit while a subtransaction is active" and similar cases manually but
let _SPI_commit() throw the error and then check in PL/Python for the
error code ERRCODE_INVALID_TRANSACTION_TERMINATION. (The code in
_SPI_commit() is there after all explicitly for PLs, so if we're not
using it, then we're doing it wrong.) And then only call
AbortOutOfAnyTransaction() (or whatever) if it's a different code, which
would mean something in the actual committing went wrong.

But in any case, for either implementation it seems then you'd get
different error behavior from .commit and .rollback calls depending on
the specific error, which seems weird.

Altogether, maybe the response to

> The existing test cases apparently fail to trip over that
> because Python just throws the exception again, but what if someone
> writes a plpython function that catches the exception and then tries
> to perform new SPI actions?

perhaps should be, don't do that then?

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Peter Eisentraut 2022-02-01 14:40:46 Re: dynamic result sets support in extended query protocol
Previous Message Bharath Rupireddy 2022-02-01 14:18:01 Re: Plug minor memleak in pg_dump