postgres crashing on a seemingly good query

From: Abhijit Menon-Sen <ams(at)oryx(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Subject: postgres crashing on a seemingly good query
Date: 2005-02-19 16:08:56
Message-ID: 20050219160856.GA743@penne.toroid.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Summary: I can crash 7.4-CVS and 8.0/HEAD by sending what appears to be
a valid query.

I'm trying to insert a unique entry into this table:

create table bodyparts (
id serial primary key,
bytes integer not null,
lines integer not null,
hash text not null,
text bytea,
data bytea
);

insert into bodyparts (bytes,lines,hash,text,data)
select $1,$2,$3,$4,$5 where not exists
(select id from bodyparts where hash=$3)

($1 = 58, $2 = 3, $3 = "3dd93158c8775c62e7a546ae1abad1da",
$4 = "Appended is one html file and one French lesson.\r\n\r\nArnt\r\n",
$5 is NULL)

I issue a Parse (leaving all the placeholder types unspecified), Bind,
Describe, Execute, and Sync sequence, and the backend segfaults during
the Execute (some whitespace munged to make lines shorter):

Program received signal SIGSEGV, Segmentation fault.
0x08075071 in ComputeDataSize (tupleDesc=0x83ed778, values=0x83edab8,
nulls=0x83edae4 " n~\177\177") at heaptuple.c:55
55 data_length = att_addlength(data_length, att[i]->attlen, values[i]);

(gdb) info local
data_length = 0
i = 0
numberOfAttributes = 5
att = (Form_pg_attribute *) 0x83ed7a4
(gdb) p att[i]
$7 = 0x83ed7d0
(gdb) p *$7
$8 = {attrelid = 0, attname = {data = "?column?", '\0' <repeats 55 times>,
alignmentDummy = 1819239231}, atttypid = 705, attstattarget = -1,
attlen = -1, attnum = 1, attndims = 0, attcacheoff = -1,
atttypmod = -1, attbyval = 0 '\0', attstorage = 112 'p',
attalign = 105 'i', attnotnull = 0 '\0', atthasdef = 0 '\0',
attisdropped = 0 '\0', attislocal = 1 '\001', attinhcount = 0}
(gdb) p values[i]
$9 = 58

Here's a backtrace:

(gdb) bt
#0 0x08075071 in ComputeDataSize (tupleDesc=0x83ed778, values=0x83edab8,
nulls=0x83edae4 " n~\177\177") at heaptuple.c:55
#1 0x08076414 in heap_formtuple (tupleDescriptor=0x83ed778, values=0x83edab8,
nulls=0x83edae4 " n~\177\177") at heaptuple.c:622
#2 0x0814e343 in ExecTargetList (targetlist=0x83ed594, targettype=0x83ed778,
econtext=0x83ed4cc, values=0x83edab8, nulls=0x83edae4 " n~\177\177",
itemIsDone=0x83edaf8, isDone=0xbfffdad4) at execQual.c:3676
#3 0x0814e3a1 in ExecProject (projInfo=0x83eda8c, isDone=0xbfffdad4)
at execQual.c:3714
#4 0x0815900b in ExecResult (node=0x83ed440) at nodeResult.c:155
#5 0x08147b9c in ExecProcNode (node=0x83ed440) at execProcnode.c:292
#6 0x0815d659 in SubqueryNext (node=0x83eb878) at nodeSubqueryscan.c:77
#7 0x0814e4d6 in ExecScan (node=0x83eb878, accessMtd=0x815d610 <SubqueryNext>)
at execScan.c:98
#8 0x0815d691 in ExecSubqueryScan (node=0x83eb878) at nodeSubqueryscan.c:102
#9 0x08147c0a in ExecProcNode (node=0x83eb878) at execProcnode.c:315
#10 0x081460f5 in ExecutePlan (estate=0x83eb284, planstate=0x83eb878,
operation=CMD_INSERT, numberTuples=0, direction=ForwardScanDirection,
dest=0x8326568) at execMain.c:1060
#11 0x08145245 in ExecutorRun (queryDesc=0x83eac44,
direction=ForwardScanDirection, count=0) at execMain.c:226
#12 0x081e41ed in ProcessQuery (parsetree=0x83df51c, plan=0x83fc408,
params=0x83eaa74, dest=0x8326568, completionTag=0xbfffde70 "")
at pquery.c:173
#13 0x081e5287 in PortalRunMulti (portal=0x83f2a7c, dest=0x8326568,
altdest=0x8326568, completionTag=0xbfffde70 "") at pquery.c:1016
#14 0x081e4adf in PortalRun (portal=0x83f2a7c, count=2147483647,
dest=0x83dad20, altdest=0x83dad20, completionTag=0xbfffde70 "")
at pquery.c:617
#15 0x081e1b86 in exec_execute_message (portal_name=0x83dac14 "",
max_rows=2147483647) at postgres.c:1673
#16 0x081e374d in PostgresMain (argc=4, argv=0x836f7d4,
username=0x836f7a4 "oryx") at postgres.c:3056
#17 0x081ad777 in BackendRun (port=0x837ef80) at postmaster.c:2816
#18 0x081acdc5 in BackendStartup (port=0x837ef80) at postmaster.c:2452
#19 0x081aaf9a in ServerLoop () at postmaster.c:1199
#20 0x081aa8b3 in PostmasterMain (argc=3, argv=0x836dd98) at postmaster.c:918
#21 0x0816b0e6 in main (argc=3, argv=0x836dd98) at main.c:268

I couldn't reproduce this with SQL PREPARE/EXECUTE statements in psql,
so I conjectured that it may have something to do with the parameter
types being unspecified. I added a statement-describe message between
the parse and the bind, however, and the server had correctly inferred
all of the types (23/23/25/17/17, i.e. INT4/INT4/TEXT/BYTEA/BYTEA).

I have a tcpdump capture of the transaction, which is available at
<http://wiw.org/~ams/crash.tcpdump>

The most convenient way to view that is to use Ethereal 0.10.9 or later,
since it includes the dissector that I wrote. Unfortunately, between the
time I contributed the code and the 0.10.9 release, someone introduced a
couple of bugs. In the presence of NULL parameter values, Ethereal may
wrongly report some Bind/Data-row messages as being malformed. :-(

You may either choose to ignore this (the hex dump shows that the packet
is correct), or recompile Ethereal with epan/dissectors/packet-pgsql.c
replaced with <http://www.oryx.com/ams/packet-pgsql.c>.

I can reproduce the problem at will, so if there's any other information
that might be useful in tracking down the problem, just ask.

-- ams

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Abhijit Menon-Sen 2005-02-19 16:24:23 Re: postgres crashing on a seemingly good query
Previous Message pgsql 2005-02-19 14:15:14 Re: Data loss, vacuum, transaction wrap-around