Karim BELABAS on Wed, 15 Jul 1998 17:33:36 +0200 (MET DST)


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

0-parameter functions (was Re: pari-2.0.10.beta)


[Gerhard Nicklasch:]
> The real problem is that cgeti(x) is getting called with x==0, which makes
> a royal mess of the PARI stack.
> 
> Karim is working on it but the mail system at U Paris Sud is STILL down
> after three days, so he may have severe difficulties communicating his
> findings.

[Looks like the mail server is up again... Hope that 
1) it will last.
2) I didn't miss anything; will check the archive later...]

[Henri Cohen:]
> As a temporary (?) fix to the bug described by M. Atria with 0-parameter
> functions,
> line 1349 of anal.c replace cgeti(nparam) by cgeti(max(1,nparam)).

[Igor Schein:]
> This still doesn't fix Gerhard's variation on the same theme:
> 
> mysqrt()=sqrtint(1)
> 1.-mysqrt()
> 
> It doubles the stack a few times, in my case up to 64M
> and then SEGFAULTs.

Hum, the minimal patch sent by Henri Cohen _should_ have worked, unless
I'm missing something and the following patch is going to fail as well,
although both patches correct a genuine bug that would fit the reported
problem... (Besides, it fixes the problem for me).

In any case, a better patch (from the point of view of code cleanliness as
opposed to minimality) calls for separating memory allocation proper from
codeword handling, as Gerhard explained. This is easily done by factoring
some code out of the cget* functions (the patch is bigger than needed since
some #define's don't belong there at all, and were moved out of the way...).
(This stack allocator existed before as a _very_ ugly macro, called
new_chunk(), which is now a decent (inlined) function.)

I have a much bigger patch, replacing all occurences of a dummy cgeti() as a
stack allocator by a call to new_chunk(). But
since all of these other cgeti abuses look unrelated to the problem at hand,
I'm not posting it yet...

Caution: if you apply this patch, GP will have to be recompiled from scratch.

   Karim.

P.S: The patch applies to a clean 2.0.10.beta, i.e undo Henri's patch first.

*** src/headers/parisys.h.orig  Wed Jun 17 16:05:34 1998
--- src/headers/parisys.h       Mon Jul 13 11:05:55 1998
***************
*** 44,46 ****
--- 44,55 ----

  #  endif
  #endif
+ #ifdef _WIN32
+ /* ANSI C does not allow to longjmp() out of a signal handler, in particular,
+  * the SIGINT handler. On Win32, the handler is executed in another thread, and
+  * longjmp'ing into another thread's stack will utterly confuse the system.
+  * Instead, we check whether win32ctrlc is set in new_chunk().
+  */
+   extern int win32ctrlc;
+   void dowin32ctrlc();
+ #endif
*** src/headers/paridecl.h.orig Wed Jul  8 13:23:53 1998
--- src/headers/paridecl.h      Mon Jul 13 13:09:19 1998
***************
*** 840,845 ****
--- 839,845 ----
  /* init.c */

  void       allocatemoremem(ulong newsize);
+ void       checkmemory(GEN x);
  void       freeall(void);
  GEN        gerepile(long ltop, long lbot, GEN q);
  void       gerepilemany(long av, GEN* g[], long n);
*** src/kernel/none/level1.h.orig       Thu Jul  9 15:17:04 1998
--- src/kernel/none/level1.h    Mon Jul 13 11:06:26 1998
***************
*** 62,67 ****
--- 62,68 ----
  void   mulssz(long x, long y, GEN z);
  GEN    negi(GEN x);
  GEN    negr(GEN x);
+ GEN    new_chunk(long x);
  GEN    rcopy(GEN x);
  void   resiiz(GEN x, GEN y, GEN z);
  GEN    resis(GEN x, long y);
***************
*** 80,113 ****

  #else /* defined(INLINE) */

! #  ifdef _WIN32
!      extern int win32ctrlc;
!      void dowin32ctrlc();
! #    define checkwin32ctrlc if (win32ctrlc) dowin32ctrlc()
! #  else
! #    define checkwin32ctrlc
! #  endif

  /* THE FOLLOWING ONES ARE IN mp.s */
  #  ifndef __M68K__

- #    ifdef MEMSTEP
-        void checkmemory(GEN x); /* in init.c */
- #    else
- #      define checkmemory(x) 
- #    endif
- #    define new_chunk(x)\
-        (((GEN) avma) - (x));\
-        if ((ulong)x > (ulong)((GEN)avma-(GEN)bot)) err(errpile);
- 
  INLINE GEN
  cgetg(long x, long y)
  {
    const GEN z = new_chunk(x);
! 
!   checkwin32ctrlc;
!   checkmemory(z); avma = (long)z;
!   z[0]=evaltyp(y) | evallg(x);
    return z;
  }

--- 81,108 ----

  #else /* defined(INLINE) */

! INLINE GEN
! new_chunk(long x)
! {
!   const GEN z = ((GEN) avma) - x;
!   if ((ulong)x > (ulong)((GEN)avma-(GEN)bot)) err(errpile);
! #ifdef MEMSTEP
!   checkmemory(z);
! #endif
! #ifdef _WIN32
!   if (win32ctrlc) dowin32ctrlc()
! #endif
!   avma = (long)z; return z;
! }

  /* THE FOLLOWING ONES ARE IN mp.s */
  #  ifndef __M68K__

  INLINE GEN
  cgetg(long x, long y)
  {
    const GEN z = new_chunk(x);
!   z[0] = evaltyp(y) | evallg(x);
    return z;
  }

***************
*** 115,123 ****
  cgeti(long x)
  {
    const GEN z = new_chunk(x);
- 
-   checkwin32ctrlc;
-   checkmemory(z); avma = (long)z;
    z[0] = evaltyp(t_INT) | evallg(x);
    return z;
  }
--- 110,115 ----
***************
*** 126,134 ****
  cgetr(long x)
  {
    const GEN z = new_chunk(x);
- 
-   checkwin32ctrlc;
-   checkmemory(z); avma = (long)z;
    z[0] = evaltyp(t_REAL) | evallg(x);
    return z;
  }
--- 118,123 ----
*** src/language/anal.c.orig    Fri Jun 26 20:59:49 1998
--- src/language/anal.c Mon Jul 13 12:35:12 1998
***************
*** 1346,1352 ****
        }
        if (analyseur != redefine_fun)
        {
!         GEN *arglist = (GEN*) cgeti(nparam);
          ch1 = analyseur; analyseur++;
          for (i=0; i<nparam; i++)
          {
--- 1346,1352 ----
        }
        if (analyseur != redefine_fun)
        {
!         GEN *arglist = (GEN*) new_chunk(nparam);
          ch1 = analyseur; analyseur++;
          for (i=0; i<nparam; i++)
          {

--
Karim Belabas                    email: Karim.Belabas@math.u-psud.fr
Dep. de Mathematiques, Bat. 425
Universite Paris-Sud             Tel: (00 33) 1 69 15 57 48
F-91405 Orsay (France)           Fax: (00 33) 1 69 15 60 19
--
PARI/GP Home Page: http://pari.home.ml.org