Thread: plpgsql functions crash cvs

plpgsql functions crash cvs

From
Kris Jurka
Date:
eKol in #postgresql reported a problem with a plpgsql function crashing
the server.  I tested the attached against 8.2cvs as of this morning
and got this stacktrace:

#0  plpgsql_xact_cb (event=XACT_EVENT_COMMIT, arg=0x0) at pl_exec.c:4521
#1  0x000000000046f43d in CallXactCallbacks (event=XACT_EVENT_COMMIT)
     at xact.c:2618
#2  0x000000000047138b in CommitTransaction () at xact.c:1534
#3  0x0000000000472be7 in CommitTransactionCommand () at xact.c:2184
#4  0x000000000058ecde in finish_xact_command () at postgres.c:2017
#5  0x0000000000590475 in exec_simple_query (
     query_string=0x8f8f28 "select admin.fn_revoke_all('public');")
     at postgres.c:1041
#6  0x00000000005917ab in PostgresMain (argc=4, argv=0x8bb360,
     username=0x8bb320 "jurka") at postgres.c:3231
#7  0x0000000000566a18 in ServerLoop () at postmaster.c:2917
#8  0x0000000000567861 in PostmasterMain (argc=3, argv=0x89b830)
     at postmaster.c:980
#9  0x00000000005250de in main (argc=3, argv=0x3e8) at main.c:254

Kris Jurka

Re: plpgsql functions crash cvs

From
Alvaro Herrera
Date:
Kris Jurka wrote:
>
> eKol in #postgresql reported a problem with a plpgsql function crashing
> the server.  I tested the attached against 8.2cvs as of this morning
> and got this stacktrace:

Interesting.  8.1 also crashes.  8.0 instead gives this output:

psql:/home/alvherre/funcs.sql:86: ERROR:  control reached end of function without RETURN
CONTEXT:  PL/pgSQL function "fn_revoke_all_functions_from"
SQL statement "SELECT  admin.fn_revoke_all_functions_from( $1 ,  $2 )"
PL/pgSQL function "fn_revoke_all" line 11 at perform
psql:/home/alvherre/funcs.sql:88: ERROR:  control reached end of function without RETURN
CONTEXT:  PL/pgSQL function "fn_revoke_all_functions_from"
SQL statement "SELECT  admin.fn_revoke_all_functions_from( $1 ,  $2 )"
PL/pgSQL function "fn_revoke_all" line 11 at perform
psql:/home/alvherre/funcs.sql:89: ERROR:  control reached end of function without RETURN
CONTEXT:  PL/pgSQL function "fn_revoke_all_functions_from"
SQL statement "SELECT  admin.fn_revoke_all_functions_from( $1 ,  $2 )"
PL/pgSQL function "fn_revoke_all" line 11 at perform
psql:/home/alvherre/funcs.sql:90: ERROR:  control reached end of function without RETURN
CONTEXT:  PL/pgSQL function "fn_revoke_all_functions_from"
SQL statement "SELECT  admin.fn_revoke_all_functions_from( $1 ,  $2 )"
PL/pgSQL function "fn_revoke_all" line 11 at perform



In 8.1, the backtrace reads thus:

(gdb) bt
#0  plpgsql_xact_cb (event=XACT_EVENT_COMMIT, arg=0x0)
    at /pgsql/source/81_rel/src/pl/plpgsql/src/pl_exec.c:4525
#1  0x080b37ed in CallXactCallbacks (event=XACT_EVENT_COMMIT)
    at /pgsql/source/81_rel/src/backend/access/transam/xact.c:2618
#2  0x080b5923 in CommitTransaction ()
    at /pgsql/source/81_rel/src/backend/access/transam/xact.c:1534
#3  0x080b73d9 in CommitTransactionCommand ()
    at /pgsql/source/81_rel/src/backend/access/transam/xact.c:2184
#4  0x081e2d8d in finish_xact_command ()
    at /pgsql/source/81_rel/src/backend/tcop/postgres.c:2006
#5  0x081e40c5 in exec_simple_query (
    query_string=0x83d011c "SELECT admin.fn_revoke_all('public');")
    at /pgsql/source/81_rel/src/backend/tcop/postgres.c:1032
#6  0x081e593d in PostgresMain (argc=4, argv=0x8372898,
    username=0x8372860 "alvherre")
    at /pgsql/source/81_rel/src/backend/tcop/postgres.c:3217
#7  0x081b771a in ServerLoop ()
    at /pgsql/source/81_rel/src/backend/postmaster/postmaster.c:2853
#8  0x081b88d4 in PostmasterMain (argc=1, argv=0x8371860)
    at /pgsql/source/81_rel/src/backend/postmaster/postmaster.c:941
#9  0x081753c9 in main (argc=1, argv=0x8371860)
    at /pgsql/source/81_rel/src/backend/main/main.c:265
(gdb) info locals
expr = (PLpgSQL_expr *) 0x7f7f7f7f
enext = <value optimized out>


So the problem seems to be that the context containing the PLpgSQL_expr
was reset too early.  I'll investigate more after dinner, if somebody
doesn't beat me to it.

--
Alvaro Herrera                                http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.

Re: plpgsql functions crash cvs

From
Tom Lane
Date:
Kris Jurka <books@ejurka.com> writes:
> eKol in #postgresql reported a problem with a plpgsql function crashing
> the server.  I tested the attached against 8.2cvs as of this morning
> and got this stacktrace:

> #0  plpgsql_xact_cb (event=XACT_EVENT_COMMIT, arg=0x0) at pl_exec.c:4521

I believe this is new as of 8.1.  The problem is that we are chasing a
list threaded through plpgsql parse structures, and since Neil's cleanup
of plpgsql space management about a year ago, those structures are no
longer guaranteed to remain in existence throughout a backend's run.
In particular, modifying the definition of a function (in this example,
by doing a REVOKE on it) when it's been used earlier in the same
transaction can lead to a dangling pointer being chased at transaction
end.

On reflection I don't see any need for the explicit list.  We are using
it just to help keep track of whether simple expressions have been
initialized in the current transaction.  It'd be better to store the
value of GetTopTransactionId into a simple expression when we init it,
and then assume it's OK as long as this matches.

Thanks for the report!

            regards, tom lane