Thread

  1. plpython crash (PG 92)

    Asif Naeem <asif.naeem@enterprisedb.com> — 2012-04-26T12:32:00Z

    Hi,
    
    PFA test case. It used simple select statement to retrieve data via
    plpython. It crashes latest pg 9.2 with the following stack trace i.e.
    
    #0  0x000000000073021f in pfree ()
    > #1  0x00007fa74b632f7a in PLy_result_dealloc () from
    > /home/masif/work/postgresql/postgresql/inst/lib/plpython2.so
    > #2  0x00007fa74b2c710b in iter_iternext (iterator=0x1ad7150) at
    > Objects/iterobject.c:74
    > #3  0x00007fa74b2934db in PyIter_Next (iter=0x1b3c5f0) at
    > Objects/abstract.c:3107
    > #4  0x00007fa74b630245 in PLy_exec_function () from
    > /home/masif/work/postgresql/postgresql/inst/lib/plpython2.so
    > #5  0x00007fa74b630c57 in plpython_call_handler () from
    > /home/masif/work/postgresql/postgresql/inst/lib/plpython2.so
    > #6  0x0000000000583907 in ExecMakeFunctionResult ()
    > #7  0x000000000057f146 in ExecProject ()
    > #8  0x0000000000596740 in ExecResult ()
    > #9  0x000000000057e708 in ExecProcNode ()
    > #10 0x000000000057d582 in standard_ExecutorRun ()
    > #11 0x000000000064f477 in PortalRunSelect ()
    > #12 0x0000000000650778 in PortalRun ()
    > #13 0x000000000064ceca in exec_simple_query ()
    > #14 0x000000000064ddc7 in PostgresMain ()
    > #15 0x000000000060bdd9 in ServerLoop ()
    > #16 0x000000000060e9d7 in PostmasterMain ()
    > #17 0x00000000005ad360 in main ()
    
    
    Apparently it is being crashed because of invalid related pointer value of
    pfree() *header->context->methods->free_p. It is reproducible with latest
    version of python i.e. Python-2.7.3 and Python-3.2.3. Thanks.
    
    Best Regards,
    Muhammad Asif Naeem
    
  2. Re: plpython crash (PG 92)

    Asif Naeem <asif.naeem@enterprisedb.com> — 2012-04-26T12:38:14Z

    FYI,
    I have observed this crash on Linux64. Thanks.
    
    Best Regards,
    Muhammad Asif Naeem
    
    On Thu, Apr 26, 2012 at 5:32 PM, Asif Naeem <asif.naeem@enterprisedb.com>wrote:
    
    > Hi,
    >
    > PFA test case. It used simple select statement to retrieve data via
    > plpython. It crashes latest pg 9.2 with the following stack trace i.e.
    >
    > #0  0x000000000073021f in pfree ()
    >> #1  0x00007fa74b632f7a in PLy_result_dealloc () from
    >> /home/masif/work/postgresql/postgresql/inst/lib/plpython2.so
    >> #2  0x00007fa74b2c710b in iter_iternext (iterator=0x1ad7150) at
    >> Objects/iterobject.c:74
    >> #3  0x00007fa74b2934db in PyIter_Next (iter=0x1b3c5f0) at
    >> Objects/abstract.c:3107
    >> #4  0x00007fa74b630245 in PLy_exec_function () from
    >> /home/masif/work/postgresql/postgresql/inst/lib/plpython2.so
    >> #5  0x00007fa74b630c57 in plpython_call_handler () from
    >> /home/masif/work/postgresql/postgresql/inst/lib/plpython2.so
    >> #6  0x0000000000583907 in ExecMakeFunctionResult ()
    >> #7  0x000000000057f146 in ExecProject ()
    >> #8  0x0000000000596740 in ExecResult ()
    >> #9  0x000000000057e708 in ExecProcNode ()
    >> #10 0x000000000057d582 in standard_ExecutorRun ()
    >> #11 0x000000000064f477 in PortalRunSelect ()
    >> #12 0x0000000000650778 in PortalRun ()
    >> #13 0x000000000064ceca in exec_simple_query ()
    >> #14 0x000000000064ddc7 in PostgresMain ()
    >> #15 0x000000000060bdd9 in ServerLoop ()
    >> #16 0x000000000060e9d7 in PostmasterMain ()
    >> #17 0x00000000005ad360 in main ()
    >
    >
    > Apparently it is being crashed because of invalid related pointer value of
    > pfree() *header->context->methods->free_p. It is reproducible with latest
    > version of python i.e. Python-2.7.3 and Python-3.2.3. Thanks.
    >
    > Best Regards,
    > Muhammad Asif Naeem
    >
    
  3. Re: plpython crash (PG 92)

    Peter Eisentraut <peter_e@gmx.net> — 2012-04-27T20:24:16Z

    On tor, 2012-04-26 at 17:32 +0500, Asif Naeem wrote:
    > PFA test case. It used simple select statement to retrieve data via
    > plpython. It crashes latest pg 9.2 with the following stack trace i.e.
    
    > Apparently it is being crashed because of invalid related pointer value of
    > pfree() *header->context->methods->free_p. It is reproducible with latest
    > version of python i.e. Python-2.7.3 and Python-3.2.3. Thanks.
    
    This is because of this code:
    
    static void
    PLy_result_dealloc(PyObject *arg)
    {
        PLyResultObject *ob = (PLyResultObject *) arg;
    
        Py_XDECREF(ob->nrows);
        Py_XDECREF(ob->rows);
        Py_XDECREF(ob->status);
        if (ob->tupdesc)
        {
            FreeTupleDesc(ob->tupdesc);  // <-- dies here
            ob->tupdesc = NULL;
        }
    
        arg->ob_type->tp_free(arg);
    }
    
    I must have been confused about the tuple descriptor APIs.  ob->tupdesc
    is created using CreateTupleDescCopy(), which copies the refcount of the
    original tuple descriptor, thus causing a failure when the (seemingly
    still referenced) tupdesc is freed.  Is this behavior correct and
    useful?
    
    The dominant coding practice appears to be to not explicitly free copied
    tuple descriptors, so maybe that should be done here as well.
    
    
    
  4. Re: plpython crash (PG 92)

    Tom Lane <tgl@sss.pgh.pa.us> — 2012-04-27T22:51:02Z

    Peter Eisentraut <peter_e@gmx.net> writes:
    > I must have been confused about the tuple descriptor APIs.  ob->tupdesc
    > is created using CreateTupleDescCopy(), which copies the refcount of the
    > original tuple descriptor,
    
    Um, surely not.  That would be nonsensical, and anyway a look at the
    code shows it isn't doing that.
    
    > thus causing a failure when the (seemingly still referenced) tupdesc
    > is freed.  Is this behavior correct and useful?
    
    I think there must be some mistake in your analysis.
    
    			regards, tom lane
    
    
  5. Re: plpython crash (PG 92)

    Tom Lane <tgl@sss.pgh.pa.us> — 2012-04-28T04:32:57Z

    Peter Eisentraut <peter_e@gmx.net> writes:
    > On tor, 2012-04-26 at 17:32 +0500, Asif Naeem wrote:
    >> PFA test case. It used simple select statement to retrieve data via
    >> plpython. It crashes latest pg 9.2 with the following stack trace i.e.
    
    >> Apparently it is being crashed because of invalid related pointer value of
    >> pfree() *header->context->methods->free_p. It is reproducible with latest
    >> version of python i.e. Python-2.7.3 and Python-3.2.3. Thanks.
    
    > This is because of this code:
    
    I traced through this test case.  The situation is:
    
    (1) PLy_spi_execute_fetch_result is executed with CurrentMemoryContext
    being the SPI Proc context for the current SPI invocation, so that's
    where CreateTupleDescCopy creates the tupledesc that's placed into
    the PLyResultObject.
    
    (2) As we fall out of the SETOF function with the first result row,
    PLy_exec_function does SPI_finish() (plpy_exec.c:146).  That causes
    the SPI contexts to go away.  The PLyResultObject's tupdesc pointer
    is now pointing at freed memory, and in a cassert build, that memory
    has been actively wiped.
    
    (3) The main executor calls back to plpython for the next value-per-call
    result.  Control goes to the PyIter_Next call at plpy_exec.c:108, which
    decides that we're done iterating (since this example only returns one
    row), and evidently it tries to deallocate the PLyResultObject
    immediately.  Whether that happens immediately or later, though,
    you're screwed because FreeTupleDesc will be invoked on garbage.
    
    I'm inclined to think that the best fix is for
    PLy_spi_execute_fetch_result to copy the tupledesc into
    TopMemoryContext, not the current context.  This is a tad scary from a
    memory leakage standpoint, but I suppose that if python fails to recover
    the PLyResultObject, this isn't the only memory that's going to be
    leaked.
    
    This area appears to be shy a regression test case or two, in any event.
    
    			regards, tom lane
    
    
  6. Re: plpython crash (PG 92)

    Peter Eisentraut <peter_e@gmx.net> — 2012-05-02T18:04:59Z

    On lör, 2012-04-28 at 00:32 -0400, Tom Lane wrote:
    > I'm inclined to think that the best fix is for
    > PLy_spi_execute_fetch_result to copy the tupledesc into
    > TopMemoryContext, not the current context.  This is a tad scary from a
    > memory leakage standpoint, but I suppose that if python fails to recover
    > the PLyResultObject, this isn't the only memory that's going to be
    > leaked.
    > 
    > This area appears to be shy a regression test case or two, in any event.
    
    Fixed like that.