Crash bug in 8.2.3 on Solaris 10/Sparc

Поиск
Список
Период
Сортировка
От Zoltan Boszormenyi
Тема Crash bug in 8.2.3 on Solaris 10/Sparc
Дата
Msg-id 4603D9E8.1010407@cybertec.at
обсуждение исходный текст
Ответы Re: Crash bug in 8.2.3 on Solaris 10/Sparc  (Zdenek Kotala <Zdenek.Kotala@Sun.COM>)
Re: Crash bug in 8.2.3 on Solaris 10/Sparc  (Tom Lane <tgl@sss.pgh.pa.us>)
Список pgsql-hackers
Hi,

we have found that psql in PostgreSQL 8.2.3
has problems connecting to the server
running on Solaris 10/Sun SPARC.

$ uname -a
SunOS dev-machine 5.10 Generic_118833-36 sun4u sparc SUNW,Sun-Fire-V440

It seems that somehow the system provided
GCC 3.4.3 miscompiles timestamptz_send()
and it segfaults. The default function looks like this:

Datum
timestamptz_send(PG_FUNCTION_ARGS)
{       TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(0);       StringInfoData buf;
       pq_begintypsend(&buf);
#ifdef HAVE_INT64_TIMESTAMP       pq_sendint64(&buf, timestamp);
#else       pq_sendfloat8(&buf, timestamp);
#endif       PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}

GDB indicates crash at the last line.
No matter how I unrolled the function calls,
the indicated crasher line was always the one
before:
       pq_sendfloat8(&buf, timestamp);

I must be a stack corruption somehow.
I also unrolled pq_sendfloat8() so the function looks like this:

Datum
timestamptz_send(PG_FUNCTION_ARGS)
{       TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(0);       StringInfoData buf;       bytea   *byteap;       union
    {               float8  f;               int64   i;       }               swap;       uint32  n32;
pq_begintypsend(&buf);
#ifdef HAVE_INT64_TIMESTAMP       pq_sendint64(&buf, timestamp);       elog(NOTICE, "timestamptz_send()
HAVE_INT64_TIMESTAMPafter
 
pq_sendint64");
#else       swap.f = (float8)timestamp;       elog(NOTICE, "timestamptz_send() int64: %lld", swap.i);       /* High
orderhalf first, since we're doing MSB-first */
 
#ifdef INT64_IS_BUSTED       /* don't try a right shift of 32 on a 32-bit word */       n32 = (swap.i < 0) ? -1 : 0;
  elog(NOTICE, "timestamptz_send() INT64_IS_BUSTED high 32: %d", n32);
 
#else       n32 = (uint32) (swap.i >> 32);       elog(NOTICE, "timestamptz_send() high 32: %d", n32);
#endif       n32 = htonl(n32);       elog(NOTICE, "timestamptz_send() htonl high 32: %d", n32);
appendBinaryStringInfo(&buf,(char *) &n32, 4);
 
       /* Now the low order half */       n32 = (uint32) swap.i;       elog(NOTICE, "timestamptz_send() low 32: %d",
n32);      n32 = htonl(n32);       elog(NOTICE, "timestamptz_send() htonl low 32: %d", n32);
appendBinaryStringInfo(&buf,(char *) &n32, 4);
 
       elog(NOTICE, "timestamptz_send() pq_sendfloat8");
#endif       byteap = (bytea *) buf.data;       elog(NOTICE, "timestamptz_send() buf->data = %p", byteap);
Assert(buf.len>= VARHDRSZ);       VARATT_SIZEP(byteap) = buf.len;       PG_RETURN_BYTEA_P(byteap);
 
}

Th crashing line according to GDB is now the elog() call after:
       swap.f = (float8)timestamp;

This is a simple explicit type cast which shouldn't cause problems,
however it is the one that somehow corrupts something on the stack
and causes the segfault upon entering the function at the next
statement.

As a workaround, we recompiled PostgreSQL 8.2.3 with--enable-integer-datetimes
and the client can connect to the server now, after initdb.

I tried to exercise calling timestamptz_send() but creating a table
with float8 field, INSERTing and SELECTing works, too.
Both textual and binary COPY FROM and COPY TO work, too.
Either these exercises didn't call pq_sendfloat8() or it
doesn't cause problems elsewhere, only in timestamptz_send().


-- 
----------------------------------
Zoltán Böszörményi
Cybertec Geschwinde & Schönig GmbH
http://www.postgresql.at/





В списке pgsql-hackers по дате отправления:

Предыдущее
От: Bruce Momjian
Дата:
Сообщение: Re: CREATE INDEX and HOT - revised design
Следующее
От: Hugh Sasse
Дата:
Сообщение: Documentation access problems.