Обсуждение: Alpha Size (size_t) != int problem

Поиск
Список
Период
Сортировка

Alpha Size (size_t) != int problem

От
Adrian Gartland
Дата:
I've gotten a fairly recent snapshot from FTP and compiled it
up on Alpha/linux.

On running, the forked process dies with a palloc error....it
was trying to grab 4 gig worth of memory.

I've tracked this problem down to
backend/utils/cache/relcache.c

in function init_irels:
len is defined as Size, which I've checked out and it turns
out to be size_t...which happens to be 8 byte on an alpha.
len is uninitialised.

further down in init_irels
if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))

which should set len to be the size of the relation read from disk.
What is happening is that 4 bytes are being read from the file
and saved in len. Writing 4 into 8 doesn't work too well so a
complete mess is made.

Initialising len to 0 fixes the problem, but I'm thinking that this
isn't the best solution. Since len is size_t, I'm figuring that the
big scheme of things is to allow for larger tables on 64 bit machines.

I'm new to the internals so I don't know if the DB files are architecture
independant (still wading through documentation)....if it isn't...then I
guess Size should be replaced with int...and all should be happy.

What is the correct way about fixing this?

My ultimate goal here is to get timestamps working correctly on the alpha.
You probably already know...but incase you didn't...

create table dat ( d date, t timestamp);
CREATE
insert into dat values ('1999-01-22', '1999-01-22 16:00:00'); 
INSERT 18602 1
select * from dat;        d|t                     
----------+----------------------
01-22-1999|2135-02-28 22:28:16+00
(1 row)

Sometimes...the select the first time returns the correct values...
but on doing the select again immidately after the first select
will return 2135 again (probably due to the caching).

Any help on where I should be looking would be greatly received!

Cheers!

-- 
Adrian Gartland - Server Development Manager
Oregan Networks UK Ltd                     Tel: +44  (0) 1530 56 33 11
Huntingdon Court, Ashby de la Zouch        Fax: +44  (0) 1530 56 33 22
Leicestershire, LE65 1AH, United Kingdom   WWW: http://www.oregan.net/



Re: [HACKERS] Alpha Size (size_t) != int problem

От
Bruce Momjian
Дата:
> 
> I've gotten a fairly recent snapshot from FTP and compiled it
> up on Alpha/linux.
> 
> On running, the forked process dies with a palloc error....it
> was trying to grab 4 gig worth of memory.
> 
> I've tracked this problem down to
> backend/utils/cache/relcache.c
> 
> in function init_irels:
> len is defined as Size, which I've checked out and it turns
> out to be size_t...which happens to be 8 byte on an alpha.
> len is uninitialised.
> 
> further down in init_irels
> if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))
> 
> which should set len to be the size of the relation read from disk.
> What is happening is that 4 bytes are being read from the file
> and saved in len. Writing 4 into 8 doesn't work too well so a
> complete mess is made.
> 
> Initialising len to 0 fixes the problem, but I'm thinking that this
> isn't the best solution. Since len is size_t, I'm figuring that the
> big scheme of things is to allow for larger tables on 64 bit machines.
> 
> I'm new to the internals so I don't know if the DB files are architecture
> independant (still wading through documentation)....if it isn't...then I
> guess Size should be replaced with int...and all should be happy.
> 
> What is the correct way about fixing this?
> 
> My ultimate goal here is to get timestamps working correctly on the alpha.
> You probably already know...but incase you didn't...
> 
> create table dat ( d date, t timestamp);
> CREATE
> insert into dat values ('1999-01-22', '1999-01-22 16:00:00'); 
> INSERT 18602 1
> select * from dat;
>          d|t                     
> ----------+----------------------
> 01-22-1999|2135-02-28 22:28:16+00
> (1 row)
> 
> Sometimes...the select the first time returns the correct values...
> but on doing the select again immidately after the first select
> will return 2135 again (probably due to the caching).
> 
> Any help on where I should be looking would be greatly received!

I have applied a fix to the tree.  The fix is to replace sizeof(int)
with sizeof(len).  I checked the rest of the source code, and couldn't
find any other places where this would be a problem.

Patch is attached.

---------------------------------------------------------------------------

Index: relcache.c
===================================================================
RCS file: /usr/local/cvsroot/pgsql/src/backend/utils/cache/relcache.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -c -r1.53 -r1.54
*** relcache.c    1999/01/17 06:18:51    1.53
--- relcache.c    1999/01/22 16:49:25    1.54
***************
*** 7,13 ****  *  *  * IDENTIFICATION
!  *      $Header: /usr/local/cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.53 1999/01/17 06:18:51 momjian Exp $
*  *-------------------------------------------------------------------------  */
 
--- 7,13 ----  *  *  * IDENTIFICATION
!  *      $Header: /usr/local/cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.54 1999/01/22 16:49:25 momjian Exp $
*  *-------------------------------------------------------------------------  */
 
***************
*** 1876,1882 ****     for (relno = 0; relno < Num_indices_bootstrap; relno++)     {         /* first read the relation
descriptorlength */
 
!         if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))         {             write_irels();
         return;
 
--- 1876,1882 ----     for (relno = 0; relno < Num_indices_bootstrap; relno++)     {         /* first read the relation
descriptorlength */
 
!         if ((nread = FileRead(fd, (char *) &len, sizeof(len))) != sizeof(len))         {             write_irels();
         return;
 
***************
*** 1899,1905 ****         ird->lockInfo = (char *) NULL;          /* next, read the access method tuple form */
!         if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))         {             write_irels();
         return;
 
--- 1899,1905 ----         ird->lockInfo = (char *) NULL;          /* next, read the access method tuple form */
!         if ((nread = FileRead(fd, (char *) &len, sizeof(len))) != sizeof(len))         {             write_irels();
         return;
 
***************
*** 1915,1921 ****         ird->rd_am = am;          /* next read the relation tuple form */
!         if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))         {             write_irels();
         return;
 
--- 1915,1921 ----         ird->rd_am = am;          /* next read the relation tuple form */
!         if ((nread = FileRead(fd, (char *) &len, sizeof(len))) != sizeof(len))         {             write_irels();
         return;
 
***************
*** 1937,1943 ****         len = ATTRIBUTE_TUPLE_SIZE;         for (i = 0; i < relform->relnatts; i++)         {
!             if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))             {
write_irels();                return;
 
--- 1937,1943 ----         len = ATTRIBUTE_TUPLE_SIZE;         for (i = 0; i < relform->relnatts; i++)         {
!             if ((nread = FileRead(fd, (char *) &len, sizeof(len))) != sizeof(len))             {
write_irels();                return;
 
***************
*** 1953,1959 ****         }          /* next, read the index strategy map */
!         if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))         {             write_irels();
         return;
 
--- 1953,1959 ----         }          /* next, read the index strategy map */
!         if ((nread = FileRead(fd, (char *) &len, sizeof(len))) != sizeof(len))         {             write_irels();
         return;
 
***************
*** 1985,1991 ****         ird->rd_istrat = strat;          /* finally, read the vector of support procedures */
!         if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))         {             write_irels();
         return;
 
--- 1985,1991 ----         ird->rd_istrat = strat;          /* finally, read the vector of support procedures */
!         if ((nread = FileRead(fd, (char *) &len, sizeof(len))) != sizeof(len))         {             write_irels();
         return;
 
***************
*** 2082,2089 ****         len = sizeof(RelationData);          /* first, write the relation descriptor length */
!         if ((nwritten = FileWrite(fd, (char *) &len, sizeof(int)))
!             != sizeof(int))             elog(FATAL, "cannot write init file -- descriptor length");          /* next,
writeout the Relation structure */
 
--- 2082,2089 ----         len = sizeof(RelationData);          /* first, write the relation descriptor length */
!         if ((nwritten = FileWrite(fd, (char *) &len, sizeof(len)))
!             != sizeof(len))             elog(FATAL, "cannot write init file -- descriptor length");          /* next,
writeout the Relation structure */
 
***************
*** 2092,2099 ****          /* next, write the access method tuple form */         len = sizeof(FormData_pg_am);
!         if ((nwritten = FileWrite(fd, (char *) &len, sizeof(int)))
!             != sizeof(int))             elog(FATAL, "cannot write init file -- am tuple form length");          if
((nwritten= FileWrite(fd, (char *) am, len)) != len)
 
--- 2092,2099 ----          /* next, write the access method tuple form */         len = sizeof(FormData_pg_am);
!         if ((nwritten = FileWrite(fd, (char *) &len, sizeof(len)))
!             != sizeof(len))             elog(FATAL, "cannot write init file -- am tuple form length");          if
((nwritten= FileWrite(fd, (char *) am, len)) != len)
 
***************
*** 2101,2108 ****          /* next write the relation tuple form */         len = sizeof(FormData_pg_class);
!         if ((nwritten = FileWrite(fd, (char *) &len, sizeof(int)))
!             != sizeof(int))             elog(FATAL, "cannot write init file -- relation tuple form length");
if((nwritten = FileWrite(fd, (char *) relform, len)) != len)
 
--- 2101,2108 ----          /* next write the relation tuple form */         len = sizeof(FormData_pg_class);
!         if ((nwritten = FileWrite(fd, (char *) &len, sizeof(len)))
!             != sizeof(len))             elog(FATAL, "cannot write init file -- relation tuple form length");
if((nwritten = FileWrite(fd, (char *) relform, len)) != len)
 
***************
*** 2112,2119 ****         len = ATTRIBUTE_TUPLE_SIZE;         for (i = 0; i < relform->relnatts; i++)         {
!             if ((nwritten = FileWrite(fd, (char *) &len, sizeof(int)))
!                 != sizeof(int))                 elog(FATAL, "cannot write init file -- length of attdesc %d", i);
       if ((nwritten = FileWrite(fd, (char *) ird->rd_att->attrs[i], len))                 != len)
 
--- 2112,2119 ----         len = ATTRIBUTE_TUPLE_SIZE;         for (i = 0; i < relform->relnatts; i++)         {
!             if ((nwritten = FileWrite(fd, (char *) &len, sizeof(len)))
!                 != sizeof(len))                 elog(FATAL, "cannot write init file -- length of attdesc %d", i);
       if ((nwritten = FileWrite(fd, (char *) ird->rd_att->attrs[i], len))                 != len)
 
***************
*** 2123,2130 ****         /* next, write the index strategy map */         len =
AttributeNumberGetIndexStrategySize(relform->relnatts,
am->amstrategies);
!         if ((nwritten = FileWrite(fd, (char *) &len, sizeof(int)))
!             != sizeof(int))             elog(FATAL, "cannot write init file -- strategy map length");          if
((nwritten= FileWrite(fd, (char *) strat, len)) != len)
 
--- 2123,2130 ----         /* next, write the index strategy map */         len =
AttributeNumberGetIndexStrategySize(relform->relnatts,
am->amstrategies);
!         if ((nwritten = FileWrite(fd, (char *) &len, sizeof(len)))
!             != sizeof(len))             elog(FATAL, "cannot write init file -- strategy map length");          if
((nwritten= FileWrite(fd, (char *) strat, len)) != len)
 
***************
*** 2132,2139 ****          /* finally, write the vector of support procedures */         len = relform->relnatts *
(am->amsupport* sizeof(RegProcedure));
 
!         if ((nwritten = FileWrite(fd, (char *) &len, sizeof(int)))
!             != sizeof(int))             elog(FATAL, "cannot write init file -- support vector length");          if
((nwritten= FileWrite(fd, (char *) support, len)) != len)
 
--- 2132,2139 ----          /* finally, write the vector of support procedures */         len = relform->relnatts *
(am->amsupport* sizeof(RegProcedure));
 
!         if ((nwritten = FileWrite(fd, (char *) &len, sizeof(len)))
!             != sizeof(len))             elog(FATAL, "cannot write init file -- support vector length");          if
((nwritten= FileWrite(fd, (char *) support, len)) != len)
 

--  Bruce Momjian                        |  http://www.op.net/~candle maillist@candle.pha.pa.us            |  (610)
853-3000+  If your life is a hard drive,     |  830 Blythe Avenue +  Christ can be your backup.        |  Drexel Hill,
Pennsylvania19026