error handling

Niels Möller nisse at lysator.liu.se
Wed Dec 17 22:04:07 UTC 2014


tg at gmplib.org (Torbjörn Granlund) writes:

> The error handler function would then use the knowledge of the
> allocation functions to clean up the memory state, and probably longjump
> to to deallocate stack.

We've discussed such hacks for memory allocation before (but now I can't
find the relevant posts...). To recap the idea:

The "protected" code should take some input mpz variables and some
output mpz_variables. The input variables are read only. All computation
takes place in newly allocated temporaries, not touching the output
variables. Only after the computation is complete and successful,
results are assigned to the output variables using mpz_swap (which can
never result in an allocation failure).

Then needs a wrapper around the protected code, first adding a
checkpoint in the allocation data structures, and a setjmp buffer. At
any allocation failure during the computation, the allocation function
should deallocate all live storage allocated after the checkpoint, and
longjmp out, and the wrapper can then return some failure indication or
raise a C++ exception or whatever. The same mechanism could clean up
allocation after other types of failures.

Does anyone know of any implementation of this?

I think one step forward might be to think about what GMP interfaces
would make it easier to implement that type of checkpointing.

Hmm. Maybe the key is to distinguish temporary allocations from more
long-lived objects. That's the real point of the interface rules for the
"protected" code above does: It ensures that *all* allocations are for
temporaries).

Then, if we make allocation and exception handling pointers
thread-local, and provide a way to push new pointers on top of the
current ones, the longjmp recovery hack could be implemented locally for
internal gmp-calls in a library, without affecting other uses of gmp in
the same executable.

Questions are: How do we make this reasonably cheap, both in terms of
execution time, and code verbosity? And can we design the mechanism so
that the C++ wrapper (as well as wrappers for high-level languages) use
the mechanism to convert failures into proper exceptions?

> I am not too fond of these global pointers.  It would be better design
> to refer the memory handling and error handling functions from each GMP
> user variable, akin to object oriented languages' vtables.  Except that
> this would make these small structures 3 times larger.

I don't think it's a good idea to put this in the mpz variables. There's
the size. And it doesn't help with temporary allocations in mpn. And
there's the head-ache of what to do with an mpz_swap where the two
mpz objects use different allocators.

> There are real scenarios where one would want different sets of
> allocation functions.  E.g., many libraries use GMP.  Some of them have
> their orn error reporting mechanisms, and memory handles.

An alternative approach in a library is to not touch the gmp allocation
functions, but let the application's main function install an
appropriate allocator. (But with the current interfaces, that makes it
difficult for libraries to use longjmp-recovery-trick from the
allocation function).

> We have another problem with the GMP structures.  On 64-bit machines,
> the 32-bit _mp_size field is starting to hurt for some applications, and
> with that also the _mp_alloc field.
>
> We might therefore consider changing these structures in an incompatible
> way.  We culd then sneak in a field for choosing 'handler functions'.
> Perhaps like this:
>
>         signed long _mp_size     : 46;
>         unsigned long _mp_alloc  : 14;  // 8-bit mantissa, 6-bit exponent
>         unsigned long _mp_handler:  4;
>         mp_limb_t _mp_d;        // 64
>
> The trickery with field sizes keeps the structure at 128 bits.  There
> will be a cost for it, though.

I'm very skeptic to the _mp_handler, I think the exception handler must
be associated with a frame on the call stack in some way.

On the other hand, we have discussed earlier to use more bits for
_mp_size, at the expense of _mp_alloc, by reducing the granularity of
the latter. I think that is a pretty good idea.

Regards,
/Niels

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid C0B98E26.
Internet email is subject to wholesale government surveillance.


More information about the gmp-devel mailing list