Karim.Belabas on Mon, 9 Apr 2001 19:29:32 +0200 (MET DST)


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

Re: catching errors


On Thu, 5 Apr 2001, Matias Atria wrote:
> I'm already resetting those signals, but how do I stop PARI from exiting
> after, say, division by zero? There is a function err_catch() but I'm not
> sure if it can be used safely outside the library (and does not seem to be
> documented)

err_catch() is meant to emulate (somewhat) the catch/throw semantics. It's
(partly) available under GP as trap().

It is safe to use it but the function is rather recent and the interface may
change in the near future (I'm not that happy about my implementation, and
it's cumbersome to use properly). That's why it's not documented yet.

See the gegal() code for how to use it. It's a bit messy:
  {
    jmp_buf env;
    void *c;
    if (setjmp(env)) { /* something went wrong */ }
    else
    {
      c = err_catch(-1, env, NULL);
      <... something that might fail badly here ...>
    }
    err_leave(&c);
  }

The -1 above traps all errors, you might wish to trap a single one (use the
keywords from parierr.h), but it's not really recommended [these keywords
have not been used in a consistent way, and most errors are simply generic
'talkers']. Don't forget the err_leave() to unset the trap  [ otherwise,
after you rontine returns without problem, a later error might trigger a
longjmp that would restore an invalid stack environment . There is some logic
to try and avoid that, but it's not foolproof ]


A simpler alternative is to write your own handler and initialize
'environnement' yourself. Currently pari_init() sets it as:

  if (INIT_JMP && setjmp(environnement))
  { /* control comes back here after an error occured */
    fprintferr("  ***   Error in the PARI system. End of program.\n");
    exit(1);
  }

When an error occurs, err() is called, then err_recover(), which ends with a
longjmp(environnement). Just before that, if the boolean 'try_to_recover' is
set to a non-zero value, recover() is called and heap memory is reclaimed, at
least the part that was allocated since last call to recover(). You probably
don't want that [then leave 'try_to_recover' to its default value: 0]

Just add your own setjmp(environnement) somewhere in your own code (after
pari_init(), but before the main call in your program [basically, make sure
the function which does the setjmp doesn't return before the lonjmp occurs!].
You'll get pari error message and control will be given back to your handler
[the trapping mechanism would also cancel the error message].


If you want a very elaborate trapping mechanism, you may want to look at
the break_loop() routine, which is activated in "trap" mode under GP [give
access to a primitive debugger when an error occurs].


Hope this helps,

    Karim.
-- 
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://www.parigp-home.de/