BUG #5906: assertion failure in AtCleanup_Portals

Started by YAMAMOTO Takashiabout 15 years ago6 messagesbugs
Jump to latest
#1YAMAMOTO Takashi
yamt@mwd.biglobe.ne.jp

The following bug has been logged online:

Bug reference: 5906
Logged by: YAMAMOTO Takashi
Email address: yamt@mwd.biglobe.ne.jp
PostgreSQL version: 9.1devel
Operating system: NetBSD current
Description: assertion failure in AtCleanup_Portals
Details:

i got the following with my application, which uses
PQsendPrepare+PQsendQueryPrepared for nearly everything
including ROLLBACK.

PostgreSQL version is 4c966d920fb75a5d0366b887c2ef28e6d87c1eda.

(gdb) bt
#0 0xbbba4cc7 in _lwp_kill () from /usr/lib/libc.so.12
#1 0xbbba4c85 in raise (s=6) at /siro/nbsd/src/lib/libc/gen/raise.c:48
#2 0xbbba445a in abort () at /siro/nbsd/src/lib/libc/stdlib/abort.c:74
#3 0x0833eae2 in ExceptionalCondition (
conditionName=0x84bf3b8 "!(portal->cleanup == ((void *)0))",
errorType=0x8371631 "FailedAssertion", fileName=0x84bf200 "portalmem.c",

lineNumber=766) at assert.c:57
#4 0x0835d4e3 in AtCleanup_Portals () at portalmem.c:766
#5 0x080c49a8 in CleanupTransaction () at xact.c:2325
#6 0x080c809b in CommitTransactionCommand () at xact.c:2503
#7 0x082845a3 in finish_xact_command () at postgres.c:2450
#8 0x08287b34 in PostgresMain (argc=2, argv=0xbb9126a4,
username=0xbb9125f8 "takashi") at postgres.c:1980
#9 0x08242306 in ServerLoop () at postmaster.c:3590
#10 0x082430b8 in PostmasterMain (argc=3, argv=0xbfbfe5a8) at
postmaster.c:1110
#11 0x081e1ac9 in main (argc=3, argv=0xbfbfe5a8) at main.c:199
(gdb) fr 4
#4 0x0835d4e3 in AtCleanup_Portals () at portalmem.c:766
766 Assert(portal->cleanup == NULL);
(gdb) p *portal
$2 = {name = 0xbb9e3d48 "", prepStmtName = 0x99b35838 "41", heap =
0x99b323e8,
resowner = 0x99b44b8c, cleanup = 0x817dd70 <PortalCleanup>, createSubid =
1,
sourceText = 0x99b3581c "ROLLBACK", commandTag = 0x8498daf "ROLLBACK",
stmts = 0x99ba681c, cplan = 0x99ba6868, portalParams = 0x0,
strategy = PORTAL_MULTI_QUERY, cursorOptions = 4, status = PORTAL_DONE,
portalPinned = 0 '\0', queryDesc = 0x0, tupDesc = 0x0, formats = 0x0,
holdStore = 0x0, holdContext = 0x0, atStart = 1 '\001', atEnd = 1 '\001',

posOverflow = 0 '\0', portalPos = 0, creation_time = 352351237783155,
visible = 1 '\001'}
(gdb)

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: YAMAMOTO Takashi (#1)
Re: BUG #5906: assertion failure in AtCleanup_Portals

"YAMAMOTO Takashi" <yamt@mwd.biglobe.ne.jp> writes:

i got the following with my application, which uses
PQsendPrepare+PQsendQueryPrepared for nearly everything
including ROLLBACK.

Can't do anything about that without a test case.

regards, tom lane

#3YAMAMOTO Takashi
yamt@mwd.biglobe.ne.jp
In reply to: Tom Lane (#2)
Re: BUG #5906: assertion failure in AtCleanup_Portals

hi,

"YAMAMOTO Takashi" <yamt@mwd.biglobe.ne.jp> writes:

i got the following with my application, which uses
PQsendPrepare+PQsendQueryPrepared for nearly everything
including ROLLBACK.

Can't do anything about that without a test case.

regards, tom lane

here's a small test case.

YAMAMOTO Takashi

#include <stdlib.h>

#include <libpq-fe.h>

int
main()
{
PGconn *conn;
PGresult *res;

conn = PQconnectdb("");
if (PQstatus(conn) != CONNECTION_OK) {
exit(1);
}
res = PQprepare(conn, "r", "ROLLBACK", 0, NULL);
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
exit(1);
}
PQclear(res);
res = PQexec(conn, "BEGIN");
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
exit(1);
}
PQclear(res);
res = PQexec(conn, "hoge");
/* a syntax error made the transaction aborted */
PQclear(res);
res = PQexecPrepared(conn, "r", 0, NULL, NULL, NULL, 0);
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
exit(1);
}
PQclear(res);
exit(0);
}

#4Itagaki Takahiro
itagaki.takahiro@gmail.com
In reply to: YAMAMOTO Takashi (#3)
Re: BUG #5906: assertion failure in AtCleanup_Portals

On Thu, Mar 3, 2011 at 09:14, YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp> wrote:

i got the following with my application, which uses
PQsendPrepare+PQsendQueryPrepared for nearly everything
including ROLLBACK.

here's a small test case.

I was able to reproduce the assertion failure.

It looks we call CreatePortal for ROLLBACK, but don't invoke
DropPortal nor AtAbort_Portals before AtCleanup_Portals.

--
Itagaki Takahiro

#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: Itagaki Takahiro (#4)
Re: BUG #5906: assertion failure in AtCleanup_Portals

Itagaki Takahiro <itagaki.takahiro@gmail.com> writes:

On Thu, Mar 3, 2011 at 09:14, YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp> wrote:

here's a small test case.

I was able to reproduce the assertion failure.

It looks we call CreatePortal for ROLLBACK, but don't invoke
DropPortal nor AtAbort_Portals before AtCleanup_Portals.

Hmm. The reason why not is that xact.c is already in TBLOCK_ABORT_END
state, ie, it knows it already did AbortTransaction and doesn't see a
need to do it again. So the portal running ROLLBACK doesn't get
cleaned up by AtAbort_Portals.

We could revert the addition of the "cleanup == NULL" assert in
AtCleanup_Portals, but I'm still feeling that that assertion is a good
thing. Maybe the cleanest fix is to have PortalRun do something to run
the cleanup hook where it does this:

/* Prevent portal's commands from being re-executed */
portal->status = PORTAL_DONE;

That should be a safe-enough place to run cleanup.

regards, tom lane

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#5)
Re: BUG #5906: assertion failure in AtCleanup_Portals

I wrote:

We could revert the addition of the "cleanup == NULL" assert in
AtCleanup_Portals, but I'm still feeling that that assertion is a good
thing. Maybe the cleanest fix is to have PortalRun do something to run
the cleanup hook where it does this:
/* Prevent portal's commands from being re-executed */
portal->status = PORTAL_DONE;

Fixed that way. Thanks for the report!

regards, tom lane