Thread: GiST on 64-bit box

GiST on 64-bit box

From
Teodor Sigaev
Date:
Hello,

We have report that all GiST opclasses cause a coredump while creating index on 
64-bit Solaris. I try to make installcheck GiST's contrib modules on DEC Alpha 
and got the same result. So it may be one problem.

Compiler:
gcc -v
Reading specs from 
/usr/local/egcs/lib/gcc-lib/alphaev56-dec-osf4.0c/egcs-2.90.23/specs
gcc version egcs-2.90.23 980102 (egcs-1.0.1 release)


Backtrace:
#0  0x12003d564 in gistdentryinit (giststate=0x11fffd820, nkey=0, e=0x1401b25a4, 
k=5370611216, r=0x140171ce8,    pg=0x1401ce620 "", o=1, b=8, l=0 '\000', isNull=0 '\000') at gist.c:1754
#1  0x12003b3b0 in gistSplit (r=0x140171ce8, buffer=-1, itup=0x140196a10, 
len=0x11fffd598, giststate=0x11fffd820,    res=0x0) at gist.c:1264
#2  0x120037be4 in gistlayerinsert (r=0x140171ce8, blkno=1075407376, 
itup=0x11fffd610, len=0x11fffd618, res=0x0,    giststate=0x11fffd820) at gist.c:515
#3  0x1200376d8 in gistdoinsert (r=0x140171ce8, itup=0x140196718, res=0x0, 
giststate=0x11fffd820) at gist.c:426
#4  0x120037228 in gistbuildCallback (index=0x140171ce8, htup=0x140196590, 
attdata=0x11fffd710,    nulls=0x11fffd790 " о\017@\001", tupleIsAlive=-24 'Х', state=0x1401ce620) 
at gist.c:275
#5  0x12008c4c4 in IndexBuildHeapScan (heapRelation=0x1, 
indexRelation=0x140171ce8, indexInfo=0x140196238,    callback=0x120037020 <gistbuildCallback>,
callback_state=0x11fffd820)at 
 
index.c:1805
#6  0x120036f70 in gistbuild (fcinfo=0x11fffd820) at gist.c:186
#7  0x1201df8c4 in OidFunctionCall3 (functionId=536860704, arg1=5370215808, 
arg2=5370223848, arg3=5370372664)    at fmgr.c:1190
...

Output to sdterr:
Unaligned access pid=6018 <postgres> va=0x1401b25a4 pc=0x12003d560 
ra=0x12003b3b0 inst=0xb6690000

Source (gist.c, around 1264 line):        /* generate the item array */        entryvec = (bytea *) palloc(VARHDRSZ +
(*len+ 1) * sizeof(GISTENTRY));        decompvec = (bool *) palloc(VARHDRSZ + (*len + 1) * sizeof(bool));
VARATT_SIZEP(entryvec)= (*len + 1) * sizeof(GISTENTRY) + VARHDRSZ;        for (i = 1; i <= *len; i++)        {
     datum = index_getattr(itup[i - 1], 1, giststate->tupdesc, &IsNull);                gistdentryinit(giststate, 0,
&((GISTENTRY*) VARDATA(entryvec))[i],                                           datum, r, p, i,
ATTSIZE(datum,giststate->tupdesc, 1, IsNull), FALSE, IsNull);                if ((!isAttByVal(giststate, 0)) &&
((GISTENTRY*) 
 
VARDATA(entryvec))[i].key != datum)                        decompvec[i] = TRUE;                else
  decompvec[i] = FALSE;        }
 

Core dump causes on first call gistdentryinit, because pointer
&((GISTENTRY *) VARDATA(entryvec))[1] has not 8-byte aligment. Difference 
between entryvec and this pointer is equal 44 bytes.

Can  you give some advice how make aligment? or, may be exist another way for 
solving...

BTW, on HPUX 11.0 all works fine.

Thank you.


-- 
Teodor Sigaev
teodor@stack.net




Re: GiST on 64-bit box

From
Tom Lane
Date:
Teodor Sigaev <teodor@stack.net> writes:
> We have report that all GiST opclasses cause a coredump while creating
> index on 64-bit Solaris. I try to make installcheck GiST's contrib
> modules on DEC Alpha and got the same result. So it may be one
> problem.

Yes.  It looks to me like GIST is broken on any platform that has 8-byte
Datum (or pointer) and requires 8-byte alignment of same.

The problem is that GISTENTRY will require 8-byte alignment on such a
platform, and this code is not honoring that: it's trying to set up an
array of GISTENTRYs starting at offset 4 in a palloc'd memory chunk.

Apparently, the reason for the offset is to stick a varlena header on
the parameter being passed to the picksplit function.  This seems like
it might be unnecessary.  Is there another way for the picksplit
function to learn the length of the array?

I think you have two possible ways to proceed:

1. Modify the code to use MAXALIGN(VARHDRSZ) rather than just VARHDRSZ
as the offset in the bogus bytea construct.  This would be messy since
you couldn't use VARDATA() anymore.

2. Forget the bytea header and just treat the object as a GISTENTRY
array.

Either one of these is going to require changing the picksplit functions
as well as the calling code, so they're both bad choices from a
maintenance point of view.  I think I lean towards #2 since it will make
the code less ugly rather than more so.
        regards, tom lane


Re: GiST on 64-bit box

From
Teodor Sigaev
Date:
My opinion is that second way is right (use GISTENTRY array). But this channge 
requires changes in GiST API: picksplit and union functions must retrieve one 
argument more. Is it possible to make for 7.2.1 or such changes must be appyed 
in TODO for 7.3 ?

Tom Lane wrote:

> I think you have two possible ways to proceed:
> 
> 1. Modify the code to use MAXALIGN(VARHDRSZ) rather than just VARHDRSZ
> as the offset in the bogus bytea construct.  This would be messy since
> you couldn't use VARDATA() anymore.
> 
> 2. Forget the bytea header and just treat the object as a GISTENTRY
> array.
> 
> Either one of these is going to require changing the picksplit functions
> as well as the calling code, so they're both bad choices from a
> maintenance point of view.  I think I lean towards #2 since it will make
> the code less ugly rather than more so.
> 
>             regards, tom lane
> 
> 


-- 
Teodor Sigaev
teodor@stack.net




Re: GiST on 64-bit box

From
Tom Lane
Date:
Teodor Sigaev <teodor@stack.net> writes:
> My opinion is that second way is right (use GISTENTRY array). But this
> channge requires changes in GiST API: picksplit and union functions
> must retrieve one argument more. Is it possible to make for 7.2.1 or
> such changes must be appyed in TODO for 7.3 ?

Hmm.  If we had any such functions installed in the standard system,
then such a change would mean an initdb, which we couldn't do for 7.2.1.

We could argue that forcing a change in a contrib module isn't an
initdb, but the argument will seem very thin to anyone who has a
running 7.2 database with GIST indexes and wants to update to 7.2.1.
They will have to reinstall their GIST support modules and recreate
their GIST indexes, AFAICS.

On the other hand, changing the signature would be a good thing if the
GIST code were tweaked to check that the referenced function had the
right signature, because that way you could raise an error at runtime
if someone tried to use a non-updated contrib module with an updated
backend.  Without some such check I foresee disasters in the field.

So I think I vote for changing the signature and tweaking initGISTstate
to verify that the number of parameters each function expects is right.

But even with that, it might be argued that we should postpone the
change till 7.3, and just say "sorry folks, GIST doesn't work on
64-bit machines for now".  Is that worse than risking update problems
for existing users of GIST indexes?  Comments anyone?
        regards, tom lane


Re: GiST on 64-bit box

From
Tom Lane
Date:
Actually, there is a third possibility, which would fix the problem
without requiring any changes in the picksplit functions.  You could
do this:
   char *storage;
   storage = palloc(MAXALIGN(VARHDRSZ) + (*len + 1) * sizeof(GISTENTRY));   entryvec = (bytea *) (storage +
MAXALIGN(VARHDRSZ)- VARHDRSZ);
 
   use entryvec as before, except final pfree is pfree(storage)

Grotty as heck, but probably the right answer for 7.2.1 to avoid the
initdb issues.

For 7.3 we could do it the other, cleaner way.
        regards, tom lane


Re: GiST on 64-bit box

From
Holger Krug
Date:
On Fri, Feb 08, 2002 at 12:42:18PM -0500, Tom Lane wrote:
> Teodor Sigaev <teodor@stack.net> writes:
> But even with that, it might be argued that we should postpone the
> change till 7.3, and just say "sorry folks, GIST doesn't work on
> 64-bit machines for now".  Is that worse than risking update problems
> for existing users of GIST indexes?  Comments anyone?

I would change it for 7.3 but have a patch somewhere downloadable for
those, who need it ASAP.

-- 
Holger Krug
hkrug@rationalizer.com


Re: GiST on 64-bit box

From
Oleg Bartunov
Date:
Hi,

I have a discussion with Teodor over the phone and we agree
this is the best for 7.2.*. Thanks Tom for the help.
btw, I think it should be noticed somewhere in documentation for developers
that pointers to "int" and "long" which are the same on 32-bit machine,
are different on the 64-bit machine.
Oleg

PS. For more than year of our GiST development we got the first report
from 64-bit machine and I think it's a good sign. This year we must
add concurrency support. We already had discussion with
Joseph Hellerstein ( the 'father' of the GiST ) about concurrency support
and perhaps we'll go along the paper by Marcel Kornacker.

On Fri, 8 Feb 2002, Tom Lane wrote:

> Actually, there is a third possibility, which would fix the problem
> without requiring any changes in the picksplit functions.  You could
> do this:
>
>     char *storage;
>
>     storage = palloc(MAXALIGN(VARHDRSZ) + (*len + 1) * sizeof(GISTENTRY));
>     entryvec = (bytea *) (storage + MAXALIGN(VARHDRSZ) - VARHDRSZ);
>
>     use entryvec as before, except final pfree is pfree(storage)
>
> Grotty as heck, but probably the right answer for 7.2.1 to avoid the
> initdb issues.
>
> For 7.3 we could do it the other, cleaner way.
>
>             regards, tom lane
>
> ---------------------------(end of broadcast)---------------------------
> TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org
>
Regards,    Oleg
_____________________________________________________________
Oleg Bartunov, sci.researcher, hostmaster of AstroNet,
Sternberg Astronomical Institute, Moscow University (Russia)
Internet: oleg@sai.msu.su, http://www.sai.msu.su/~megera/
phone: +007(095)939-16-83, +007(095)939-23-83



Re: GiST on 64-bit box

From
Teodor Sigaev
Date:
This patch solve the problem with unaligned access on 64-bit box. Please apply
it for 7.2.1.

Tested on DEC Alpha.

Tom Lane wrote:

> Actually, there is a third possibility, which would fix the problem
> without requiring any changes in the picksplit functions.  You could
> do this:
>
>     char *storage;
>
>     storage = palloc(MAXALIGN(VARHDRSZ) + (*len + 1) * sizeof(GISTENTRY));
>     entryvec = (bytea *) (storage + MAXALIGN(VARHDRSZ) - VARHDRSZ);
>
>     use entryvec as before, except final pfree is pfree(storage)
>
> Grotty as heck, but probably the right answer for 7.2.1 to avoid the
> initdb issues.
>
> For 7.3 we could do it the other, cleaner way.
>
>             regards, tom lane
>
>


--
Teodor Sigaev
teodor@stack.net


Attachment

Re: GiST on 64-bit box

From
Teodor Sigaev
Date:
We got the report about this patch on 64-bit Solaris: it's work.

Teodor Sigaev wrote:
> This patch solve the problem with unaligned access on 64-bit box. Please 
> apply it for 7.2.1.
> 
> Tested on DEC Alpha.
> 
> Tom Lane wrote:
> 
>> Actually, there is a third possibility, which would fix the problem
>> without requiring any changes in the picksplit functions.  You could
>> do this:
>>
>>     char *storage;
>>
>>     storage = palloc(MAXALIGN(VARHDRSZ) + (*len + 1) * 
>> sizeof(GISTENTRY));
>>     entryvec = (bytea *) (storage + MAXALIGN(VARHDRSZ) - VARHDRSZ);
>>
>>     use entryvec as before, except final pfree is pfree(storage)
>>
>> Grotty as heck, but probably the right answer for 7.2.1 to avoid the
>> initdb issues.
>>
>> For 7.3 we could do it the other, cleaner way.
>>
>>             regards, tom lane
>>
>>
> 
> 
> 
> ------------------------------------------------------------------------
> 
> 
> ---------------------------(end of broadcast)---------------------------
> TIP 2: you can get off all lists at once with the unregister command
>     (send "unregister YourEmailAddressHere" to majordomo@postgresql.org)
> 


-- 
Teodor Sigaev
teodor@stack.net



Re: GiST on 64-bit box

From
Tom Lane
Date:
Teodor Sigaev <teodor@stack.net> writes:
> This patch solve the problem with unaligned access on 64-bit
> box. Please apply it for 7.2.1.

Patch applied, thanks.
        regards, tom lane