Odd behavior with PG_TRY

From: Jim Nasby <Jim(dot)Nasby(at)BlueTreble(dot)com>
To: Pg Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Odd behavior with PG_TRY
Date: 2017-01-02 05:44:58
Message-ID: 2a7fcc2c-7fe9-4472-fa6b-d7b453816d83@BlueTreble.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

In the attached patch (snippet below), I'm seeing something strange with
args->in.r.atts[]. Prior to entering the PG_TRY block, I can inspect
things in lldb just fine:

(lldb) call args->in.r.atts[0].func
(PLyDatumToObFunc) $49 = 0x000000010fc4dc70
(plpython3.so`PLyString_FromDatum at plpy_typeio.c:621)
(lldb) call &args->in.r.atts[0]
(PLyDatumToOb *) $50 = 0x00007fd2b302f6d0
(lldb) call args->in.r.atts[0]
(PLyDatumToOb) $51 = {
func = 0x000000010fc4dc70 (plpython3.so`PLyString_FromDatum at
plpy_typeio.c:621)
typfunc = {
fn_addr = 0x000000010f478b50 (postgres`textout at varlena.c:521)
fn_oid = 47
...

But I'm getting a EXC_BAD_ACCESS (code=1, address=0xb302f6d0) on the
last if in the snippet below. Looking at the variables again, I see:

(lldb) call args->in.r.atts[i].func
error: Couldn't apply expression side effects : Couldn't dematerialize a
result variable: couldn't read its memory
(lldb) call args->in.r.atts[i]
error: Couldn't apply expression side effects : Couldn't dematerialize a
result variable: couldn't read its memory

I saw the comment on PG_TRY about marking things as volatile, but my
understanding from the comment is I shouldn't even need to do that,
since these variables aren't being modified.

> static bool
> PLy_CSreceive(TupleTableSlot *slot, DestReceiver *self)
> {
> volatile TupleDesc desc = slot->tts_tupleDescriptor;
> volatile CallbackState *myState = (CallbackState *) self;
> volatile PLyTypeInfo *args = myState->args;
>
> PLyExecutionContext *old_exec_ctx = PLy_switch_execution_context(myState->exec_ctx);
> MemoryContext scratch_context = PLy_get_scratch_context(myState->exec_ctx);
> MemoryContext oldcontext = CurrentMemoryContext;
>
> /* Verify saved state matches incoming slot */
> Assert(myState->desc == desc);
> Assert(args->in.r.natts == desc->natts);
>
> /* Make sure the tuple is fully deconstructed */
> slot_getallattrs(slot);
>
> MemoryContextSwitchTo(scratch_context);
>
> PG_TRY();
> {
> int i, rv;
>
> /*
> * Do the work in the scratch context to avoid leaking memory from the
> * datatype output function calls.
> */
> for (i = 0; i < desc->natts; i++)
> {
> PyObject *value = NULL;
>
> if (desc->attrs[i]->attisdropped)
> continue;
>
> if (myState->lists[i] == NULL)
> ereport(ERROR,
> (errmsg("missing list for attribute %d", i)));
> /* XXX If the function can't be null, ditch that check */
> if (slot->tts_isnull[i] || args->in.r.atts[i].func == NULL)
--
Jim Nasby, Data Architect, Blue Treble Consulting, Austin TX
Experts in Analytics, Data Architecture and PostgreSQL
Data in Trouble? Get it in Treble! http://BlueTreble.com
855-TREBLE2 (855-873-2532)

Attachment Content-Type Size
plpython_callbeck.diff text/plain 15.2 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Amit Kapila 2017-01-02 05:59:00 Re: Cache Hash Index meta page.
Previous Message Pavan Deolasee 2017-01-02 05:29:59 Re: rewrite HeapSatisfiesHOTAndKey