gmake check fails on Solaris 8 with Sun cc

Started by Steve Nicolaiabout 25 years ago2 messageshackers
Jump to latest
#1Steve Nicolai
snicolai@mac.com

Continuing on my quest to get 7.1 to build on Solaris 8 with
Sun's cc 5.0, I found an alignment problem in
backend/access/heap/tuptoaster.c

(/opt/SUNWspro/bin/../WS5.0/bin/sparcv9/dbx) where
=>[1] toast_save_datum(rel = 0x5fb4c8, mainoid = 18714U, attno = 7, value =
6548664U), line 816 in "tuptoaster.c"
[2]: toast_insert_or_update(rel = 0x5fb4c8, newtup = 0x653c98, oldtup = (nil)), line 493 in "tuptoaster.c"
(nil)), line 493 in "tuptoaster.c"
[3]: heap_tuple_toast_attrs(rel = 0x5fb4c8, newtup = 0x653c98, oldtup = (nil)), line 66 in "tuptoaster.c"
(nil)), line 66 in "tuptoaster.c"
[4]: heap_insert(relation = 0x5fb4c8, tup = 0x653c98), line 1316 in "heapam.c"
"heapam.c"
[5]: update_attstats(relid = 17058U, natts = 7, vacattrstats = 0x627920), line 619 in "analyze.c"
line 619 in "analyze.c"
[6]: analyze_rel(relid = 17058U, anal_cols2 = (nil), MESSAGE_LEVEL = -2), line 242 in "analyze.c"
line 242 in "analyze.c"
[7]: vac_vacuum(VacRelP = (nil), analyze = '\001', anal_cols2 = (nil)), line 248 in "vacuum.c"
line 248 in "vacuum.c"
[8]: vacuum(vacrel = (nil), verbose = '\0', analyze = '\001', anal_cols = (nil)), line 163 in "vacuum.c"
(nil)), line 163 in "vacuum.c"
[9]: ProcessUtility(parsetree = 0x5a8358, dest = Debug), line 711 in "utility.c"
"utility.c"
[10]: pg_exec_query_string(query_string = 0x5a81b8 "VACUUM ANALYZE\n", dest = Debug, parse_context = 0x599a60), line 773 in "postgres.c"
= Debug, parse_context = 0x599a60), line 773 in "postgres.c"
[11]: PostgresMain(argc = 7, argv = 0xffbef93c, real_argc = 7, real_argv = 0xffbef93c, username = 0x490e28 "steven"), line 1904 in "postgres.c"
0xffbef93c, username = 0x490e28 "steven"), line 1904 in "postgres.c"
[12]: main(argc = 7, argv = 0xffbef93c), line 171 in "main.c"

(/opt/SUNWspro/bin/../WS5.0/bin/sparcv9/dbx) list 813 +7
813 * Build a tuple
814 */
815 t_values[1] = Int32GetDatum(chunk_seq++);
816 VARATT_SIZEP(chunk_data) = chunk_size + VARHDRSZ;
817 memcpy(VARATT_DATA(chunk_data), data_p, chunk_size);
818 toasttup = heap_formtuple(toasttupDesc, t_values,
t_nulls);
819 if (!HeapTupleIsValid(toasttup))
820 elog(ERROR, "Failed to build TOAST tuple");

(/opt/SUNWspro/bin/../WS5.0/bin/sparcv9/dbx) list 737 +14
737 static Datum
738 toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum
value)
739 {
740 Relation toastrel;
741 Relation toastidx;
742 HeapTuple toasttup;
743 InsertIndexResult idxres;
744 TupleDesc toasttupDesc;
745 Datum t_values[3]heap_tuple_toast_attrs(rel = 0x5fb4c8, newtup = 0x653c98, oldtup = (nil)), line 66 in "tuptoaster.c";
746 char t_nulls[3]heap_tuple_toast_attrs(rel = 0x5fb4c8, newtup = 0x653c98, oldtup = (nil)), line 66 in "tuptoaster.c";
747 varattrib *result;
748 char chunk_data[VARHDRSZ + TOAST_MAX_CHUNK_SIZE];
749 int32 chunk_size;
750 int32 chunk_seq = 0;
751 char *data_p;

VARATT_SIZEP casts the char pointer to a varattrib pointer which must
be int32 aligned. Nothing requires the char pointer to be so aligned.

The following cheap and ugly patch gets around that problem. I have
not checked the source for other places where this would need to be
fixed. If you know of a better way to fix this, go ahead and use it.

Index: src/backend/access/heap/tuptoaster.c
===================================================================
RCS file: 
/home/projects/pgsql/cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v
retrieving revision 1.20
diff -u -r1.20 tuptoaster.c
--- src/backend/access/heap/tuptoaster.c        2001/03/23 04:49:51     1.20
+++ src/backend/access/heap/tuptoaster.c        2001/03/24 23:44:07
@@ -745,7 +745,10 @@
        Datum           t_values[3];
        char            t_nulls[3];
        varattrib  *result;
-       char            chunk_data[VARHDRSZ + TOAST_MAX_CHUNK_SIZE];
+       union {
+               varattrib       a;
+               char            d[VARHDRSZ + TOAST_MAX_CHUNK_SIZE];
+       } chunk_data;
        int32           chunk_size;
        int32           chunk_seq = 0;
        char       *data_p;
@@ -780,7 +783,7 @@
         * Initialize constant parts of the tuple data
         */
        t_values[0] =
ObjectIdGetDatum(result->va_content.va_external.va_valueid);
-       t_values[2] = PointerGetDatum(chunk_data);
+       t_values[2] = PointerGetDatum(&chunk_data);
        t_nulls[0] = ' ';
        t_nulls[1] = ' ';
        t_nulls[2] = ' ';
@@ -813,8 +816,8 @@
                 * Build a tuple
                 */
                t_values[1] = Int32GetDatum(chunk_seq++);
-               VARATT_SIZEP(chunk_data) = chunk_size + VARHDRSZ;
-               memcpy(VARATT_DATA(chunk_data), data_p, chunk_size);
+               VARATT_SIZEP(&chunk_data) = chunk_size + VARHDRSZ;
+               memcpy(VARATT_DATA(&chunk_data), data_p, chunk_size);
                toasttup = heap_formtuple(toasttupDesc, t_values, t_nulls);
                if (!HeapTupleIsValid(toasttup))
                        elog(ERROR, "Failed to build TOAST tuple");

With this patch applied, make check gets through database initialization.

Steve Nicolai

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Steve Nicolai (#1)
Re: gmake check fails on Solaris 8 with Sun cc

Steve Nicolai <snicolai@mac.com> writes:

Continuing on my quest to get 7.1 to build on Solaris 8 with
Sun's cc 5.0, I found an alignment problem in
backend/access/heap/tuptoaster.c

Good catch. I fixed a couple similar problems (assuming that a local
"char buffer[N]" object would be aligned on better-than-char boundaries)
in xlog.c not long ago. I wonder if any others are lurking?

-       char            chunk_data[VARHDRSZ + TOAST_MAX_CHUNK_SIZE];
+       union {
+               varattrib       a;
+               char            d[VARHDRSZ + TOAST_MAX_CHUNK_SIZE];
+       } chunk_data;

This is pretty ugly, it'd be better to use a struct of a struct-varlena
header followed by a char[TOAST_MAX_CHUNK_SIZE] data area. Will fix.

regards, tom lane