Gerhard Niklasch on Sun, 16 Jul 2000 03:01:03 +0200 (MET DST)


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

Re: Wrong layout of the return value of gpow()?


In response to:
> Message-ID: <20000714171541.A19395@monk.mps.ohio-state.edu>
> Date: Fri, 14 Jul 2000 17:15:41 -0400
> From: Ilya Zakharevich <ilya@math.ohio-state.edu>
> Cc: thumper@bsi.menlo-park.ca.us

> Here is the result I get from gpow():
> 
> (/opt/SUNWspro/bin/../WS5.0/bin/sparcv9/dbx) p RETVAL
> RETVAL = 0x644460
> (/opt/SUNWspro/bin/../WS5.0/bin/sparcv9/dbx) x 0x00644450/8
> 0x00644450:      0x00000004 0x02000003 0x40000003 0x00000001

(i.e. one unrelated word and a 3-word PARI integer with value 1)

> 0x00644460:      0x06000003 0x006e23a0 0x00644454 0x02000003

(i.e. the three-word t_INTMOD:  codeword, modulus pointer, and
representative pointer;  followed by another unrelated word)

> As you can see, RETVAL[2] is less than RETVAL.  This causes a segfault
> in Math::Pari.  Is it a bug?

That is the normal arrangement -- the parent object is created
first, and its child object(s) is (are) created after it and
thus below it on the stack.

RETVAL[1] looks more suspect to me, but there's no way of telling
from the information shown whether 0x6e23a0 is itself on the PARI
stack or  (which would be likely for an INTMOD)  whether it points
to a cloned t_INT on the heap.

> The possible reason is the following chunk of trans1.c:
> 
>   427       case t_INTMOD:
>   428         y=cgetg(3,tx); copyifstack(x[1],y[1]);
>   429         y[2]=(long)powmodulo((GEN)x[2],n,(GEN)x[1]);
>   430         return y;

[*blink* I spot a -GN in a comment round here, so I guess I'm partly
responsible for some of these lines ;]

...which should not fail to copy the input modulus x[1] into the
result modulus y[1] if x[1] is an object on the stack  (this to
avoid creating an object occupying a non-contiguous piece of the
stack).  RETVAL[1] was not copied as an object, it was just copied
as a pointer, so it is probably not on the stack, and the object
returned as y, or RETVAL, is legal.

What pointer is the perl module tripping over, then?  Where was
gpow() called from, and what did the caller (attempt to) do with
the return value?  Stacktrace at the time of the SIGSEGV?

Cheers, Gerhard