Re: Upstream patch to remove abort() that occur during memory overflow
Il 2020-09-13 11:38 t...@gmplib.org ha scritto: Marco Bodrato writes: With ABI=64 I get: 16777216 ^ 768614336404564651 = 256 With ABI=32 I get: 16777216 ^ 178956971 = 256 Not a signal, nor an abort, simply an incorrect result :-) That's undesirable. I thought we cought overflows also in this difficult a^b case by (indirectly means of allocation errors). Yet another... $ cat provo.c #include #include "gmp.h" int main () { unsigned long b, e; mpz_t p; mpz_t bz; mpz_init (p); mpz_init (bz); b = 24 * GMP_NUMB_BITS; mpz_setbit (bz, b); e = ~0UL / 24 + 1; mpz_pow_ui (p, bz, e); gmp_printf ("(2 ^ %lu) ^ %lu = %Zd\n", b, e, p); mpz_clear (bz); mpz_clear (p); } $ gcc provo.c -lgmp -o provo&& ./provo (2 ^ 1536) ^ 768614336404564651 = 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096 And here is a possible patch (for the 6.2 branch): $ hg diff mpz diff -r e1fd9db13b47 mpz/n_pow_ui.c --- a/mpz/n_pow_ui.cTue Dec 22 23:49:51 2020 +0100 +++ b/mpz/n_pow_ui.cSat Jun 12 15:24:36 2021 +0200 @@ -206,11 +206,33 @@ /* Strip low zero limbs from b. */ rtwos_limbs = 0; +#if 1 for (blimb = *bp; blimb == 0; blimb = *++bp) { rtwos_limbs += e; + if (UNLIKELY (rtwos_limbs < e)) + { + fprintf (stderr, "gmp: overflow in mpz type\n"); + abort (); + } bsize--; ASSERT (bsize >= 1); } +#else + blimb = *bp; + if (blimb == 0) +{ + do + ++rtwos_limbs; + while ((blimb = *++bp) == 0); + bsize -= rtwos_limbs; ASSERT (bsize >= 1); + umul_ppmm (ovfl, rtwos_limbs, e, rtwos_limbs); + if (ovfl) + { + fprintf (stderr, "gmp: overflow in mpz type\n"); + abort (); + } +} +#endif TRACE (printf ("trailing zero rtwos_limbs=%ld\n", rtwos_limbs)); /* Strip low zero bits from b. */ As you can see, I tried two different patches. One adds a (well predicted?) branch in the (on average O(1)) loop. The other uses a multiplication. But we should probably consider to add a piece of code, at the beginning of the function, estimating the total size of the result, to avoid so many spurious checks... Ĝis, m ___ gmp-bugs mailing list gmp-bugs@gmplib.org https://gmplib.org/mailman/listinfo/gmp-bugs
Re: Upstream patch to remove abort() that occur during memory overflow
Marco Bodrato writes: With ABI=64 I get: 16777216 ^ 768614336404564651 = 256 With ABI=32 I get: 16777216 ^ 178956971 = 256 Not a signal, nor an abort, simply an incorrect result :-) That's undesirable. I thought we cought overflows also in this difficult a^b case by (indirectly means of allocation errors). -- Torbjörn Please encrypt, key id 0xC8601622 ___ gmp-bugs mailing list gmp-bugs@gmplib.org https://gmplib.org/mailman/listinfo/gmp-bugs
Re: Upstream patch to remove abort() that occur during memory overflow
Ciao, Il 2020-09-03 19:22 ni...@lysator.liu.se ha scritto: Mustafa Mohamad writes: Currently GMP aborts which sends SIGBART and forcibly aborts Julia or any linked program. With the above patch, GMP will instead throw a __GMP_ALLOC_OVERFLOW_FUNC Instead of forcibly aborting Hi, I understand aborting may be undesirable, but can you provide a bit more context. How do you handle the callback on overflow? If you longjmp out, how do you arrange so that your mpz variables are in a consistent state? I believe that a "safe" mpz type, is anyway difficult to obtain. We may say that if the result is outside of the range supported by mpz, the behavior is undefined. Try the following code on a Linux or BSD system. int main (int argc, char *argv[]) { unsigned long b, e; mpz_t p; mpz_init (p); b = 1; b <<= 24; e = ~0UL / 24 + 1; mpz_ui_pow_ui (p, b, e); gmp_printf ("%lu ^ %lu = %Zd", b, e, p); mpz_clear (p); return 0; } With ABI=64 I get: 16777216 ^ 768614336404564651 = 256 With ABI=32 I get: 16777216 ^ 178956971 = 256 Not a signal, nor an abort, simply an incorrect result :-) Anyway this patch might be a way to give a little bit more control to the programs using the library... Ĝis, m ___ gmp-bugs mailing list gmp-bugs@gmplib.org https://gmplib.org/mailman/listinfo/gmp-bugs
Re: Upstream patch to remove abort() that occur during memory overflow
Mustafa Mohamad writes: > Currently GMP aborts which sends SIGBART and forcibly aborts Julia or any > linked program. With the above patch, GMP will instead throw a > __GMP_ALLOC_OVERFLOW_FUNC > Instead of forcibly aborting Hi, I understand aborting may be undesirable, but can you provide a bit more context. How do you handle the callback on overflow? If you longjmp out, how do you arrange so that your mpz variables are in a consistent state? Regards, /Niels -- Niels Möller. PGP-encrypted email is preferred. Keyid 368C6677. Internet email is subject to wholesale government surveillance. ___ gmp-bugs mailing list gmp-bugs@gmplib.org https://gmplib.org/mailman/listinfo/gmp-bugs
Upstream patch to remove abort() that occur during memory overflow
Dear developers, Below we at the Julia team would love to see the following patch upstreamed: https://github.com/JuliaLang/julia/blob/master/deps/patches/gmp_alloc_overflow_func.patch Rationale: Currently GMP aborts which sends SIGBART and forcibly aborts Julia or any linked program. With the above patch, GMP will instead throw a __GMP_ALLOC_OVERFLOW_FUNC Instead of forcibly aborting Thanks for your consideration. Best, Mustafa ___ gmp-bugs mailing list gmp-bugs@gmplib.org https://gmplib.org/mailman/listinfo/gmp-bugs