Gerhard Niklasch on Tue, 14 Jul 1998 13:37:15 +0200 (MET DST)


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: pari-2.0.10.beta


In (further) response to:
> Message-Id: <15985.199807140825@omega.ex.ac.uk.maths.exeter.ac.uk>
> Date: Tue, 14 Jul 1998 09:25:47 +0100
> From: "John Cremona (Maths)" <cremona@noether.ex.ac.uk>
> 
> For what it's worth, I get no crash with this

(by lucky accident)

> but it does give the wrong answer:
> gp > my()=sqrtint(1)
> gp > 1.-my()
> %2 = -1		<-----	?????

Here's a somewhat more detailed explanation:

(1) my() is defined and remembered by gp as a parameterless user
function.

(2) my() is getting called with the empty pair of parentheses.

(3) The parser upon seeing this allocates a PARI integer on the
stack, reserving nparam words, where nparam is the remembered number
of parameters that go with the "my" identifier -- zero in this case.
Normally the words would be filled with pointers to the actual
parameter values  (overwriting even the type t_INT and length
codeword of the `integer', which doesn't matter since the object
will be silently discarded at the next garbage collection, after
the function call returns).

Unfortunately, the allocation call cgeti(0), after checking that
allocating 0 extra words doesn't overflow the stack, writes a
t_INT and length 0 codeword into the word at the current head of
the stack -- overwriting the type and length codeword of the
previously youngest object on the stack, which happens to be the
real number on the left of the + or - sign.  Since the internal
data format of reals and integers is rather different, and since
even the length of the object is wrong, results may vary between
a bogus value and utter memory corruption  (as the garbage collector
tries to figure out what is left on the stack and stumbles over a
piece of the former real sticking out beyond the present `integer'...).

Karim mailed me on Monday that he was fixing this properly and fixing
something else in the vicinity;  it isn't entirely trivial since cgeti()
is one of the most frequently called functions in PARI and whatever
checking it does needs to be done _fast_.  If I understood him correct-
ly, he is separating the `allocate n words on the stack after checking
there's room for them' part from the `initialize the codeword at the
head of the new object' part, so that we can (safely) call the former
in situations which might involve a length of 0, without accidentally
doing the latter (which would be wrong in such situations).

Unfortunately, the mathematics department mail server at U Paris-Sud
Orsay has been down for several days  (and today is the French National
Holiday, too),  and although Karim had suggested to contact him via
the pari@math.u-bordeaux.fr address, I'm now seeing extra bounces as
that address is attempting in vain to forward to Orsay...  (I hope
Karim can still read mail sent to that address and stored locally
besides being forwarded.)

So, please consider this a `This problem is known and has been analyzed
and is being dealt with' trouble ticket and move on to find some _other_
bugs! ;^)  Surely there must be more... :^)

Thanks, Gerhard "and I know of at least one"