Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re^3: Influencing the Gconvert macro

by syphilis (Archbishop)
on Sep 30, 2020 at 14:27 UTC ( [id://11122370]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Influencing the Gconvert macro
in thread Influencing the Gconvert macro

If you can't or won't spend time in fixing compline/d_gconvert.U ...

If I can fix it, then I will undertake to do so.
At the moment, however, I have no idea how d_gconvert.U fits into "the scheme of things".
AFAICS, it's not part of the perl source.

... but I am always scared of interpolation when requiring quotes

I bothers me a bit, too. Although the configure option that I used seems to have done the trick, it wasn't exactly noiseless:
In file included from sv.c:32:0: sv.c: In function ‘Perl_sv_vcatpvfn_flags’: config.h:909:39: warning: ‘%.*g’ directive writing between 1 and 133 b +ytes into a region of size 127 [-Wformat-overflow=] #define Gconvert(x,n,t,b) sprintf((b),"%.*g",(n),(x)) ^ perl.h:6791:13: note: in definition of macro ‘WITH_LC_NUMERIC_SET_TO_N +EEDED_IN’ block; + \ ^~~~~ sv.c:48:5: note: in expansion of macro ‘PERL_UNUSED_RESULT’ PERL_UNUSED_RESULT(Gconvert((NV)(nv), (int)ndig, 0, buffer)) ^~~~~~~~~~~~~~~~~~ sv.c:48:24: note: in expansion of macro ‘Gconvert’ PERL_UNUSED_RESULT(Gconvert((NV)(nv), (int)ndig, 0, buffer)) ^~~~~~~~ sv.c:13118:21: note: in expansion of macro ‘SNPRINTF_G’ SNPRINTF_G(fv, ebuf, sizeof(ebuf), precis) ^ config.h:909:39: note: assuming directive output of 132 bytes #define Gconvert(x,n,t,b) sprintf((b),"%.*g",(n),(x)) ^ perl.h:6791:13: note: in definition of macro ‘WITH_LC_NUMERIC_SET_TO_N +EEDED_IN’ block; + \ ^~~~~ sv.c:48:5: note: in expansion of macro ‘PERL_UNUSED_RESULT’ PERL_UNUSED_RESULT(Gconvert((NV)(nv), (int)ndig, 0, buffer)) ^~~~~~~~~~~~~~~~~~ sv.c:48:24: note: in expansion of macro ‘Gconvert’ PERL_UNUSED_RESULT(Gconvert((NV)(nv), (int)ndig, 0, buffer)) ^~~~~~~~ sv.c:13118:21: note: in expansion of macro ‘SNPRINTF_G’ SNPRINTF_G(fv, ebuf, sizeof(ebuf), precis) ^ In file included from /usr/include/stdio.h:862:0, from perlio.h:41, from iperlsys.h:50, from perl.h:3934, from sv.c:32: /usr/include/x86_64-linux-gnu/bits/stdio2.h:33:10: note: ‘__builtin___ +sprintf_chk’ output between 2 and 134 bytes into a destination of siz +e 127 return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ __bos (__s), __fmt, __va_arg_pack ()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from sv.c:32:0: config.h:909:39: warning: ‘%.*g’ directive writing between 1 and 133 b +ytes into a region of size 127 [-Wformat-overflow=] #define Gconvert(x,n,t,b) sprintf((b),"%.*g",(n),(x)) ^ perl.h:6791:13: note: in definition of macro ‘WITH_LC_NUMERIC_SET_TO_N +EEDED_IN’ block; + \ ^~~~~ sv.c:48:5: note: in expansion of macro ‘PERL_UNUSED_RESULT’ PERL_UNUSED_RESULT(Gconvert((NV)(nv), (int)ndig, 0, buffer)) ^~~~~~~~~~~~~~~~~~ sv.c:48:24: note: in expansion of macro ‘Gconvert’ PERL_UNUSED_RESULT(Gconvert((NV)(nv), (int)ndig, 0, buffer)) ^~~~~~~~ sv.c:13118:21: note: in expansion of macro ‘SNPRINTF_G’ SNPRINTF_G(fv, ebuf, sizeof(ebuf), precis) ^ config.h:909:39: note: assuming directive output of 132 bytes #define Gconvert(x,n,t,b) sprintf((b),"%.*g",(n),(x)) ^ perl.h:6791:13: note: in definition of macro ‘WITH_LC_NUMERIC_SET_TO_N +EEDED_IN’ block; + \ ^~~~~ sv.c:48:5: note: in expansion of macro ‘PERL_UNUSED_RESULT’ PERL_UNUSED_RESULT(Gconvert((NV)(nv), (int)ndig, 0, buffer)) ^~~~~~~~~~~~~~~~~~ sv.c:48:24: note: in expansion of macro ‘Gconvert’ PERL_UNUSED_RESULT(Gconvert((NV)(nv), (int)ndig, 0, buffer)) ^~~~~~~~ sv.c:13118:21: note: in expansion of macro ‘SNPRINTF_G’ SNPRINTF_G(fv, ebuf, sizeof(ebuf), precis) ^ In file included from /usr/include/stdio.h:862:0, from perlio.h:41, from iperlsys.h:50, from perl.h:3934, from sv.c:32: /usr/include/x86_64-linux-gnu/bits/stdio2.h:33:10: note: ‘__builtin___ +sprintf_chk’ output between 2 and 134 bytes into a destination of siz +e 127 return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ __bos (__s), __fmt, __va_arg_pack ()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Of course, I probably should at least run make test before I start getting too excited about how successful it has been ;-)

Cheers,
Rob

Replies are listed 'Best First'.
Re^4: Influencing the Gconvert macro
by Tux (Canon) on Sep 30, 2020 at 14:54 UTC

    But it is dear hacker, it is! (free interpretation of Jethro Tull's "But you can Guru, You can" in the story of the Hare who lost his spectacles)

    Please see d_gconvert.U.

    Short summary, these units are parsed, selected and ordered according to the requirements of the perl source itself and than remodelled into the script that is called Configure.

    If you dare start the journey, read the README to start this early in the perl configuration process.


    Enjoy, Have FUN! H.Merijn
Re^4: Influencing the Gconvert macro
by hv (Prior) on Oct 01, 2020 at 04:00 UTC

    I've seen such warnings in smoke logs a number of times, and tried to investigate at least a couple of times without success; I'd love (someone) to get to the bottom of it, at least to understand if it's a real problem (that needs to be fixed by increasing a buffer size).

    I've never seen anyone report an actual problem relating to the warning though.

    Hugo

      I'd love (someone) to get to the bottom of it, at least to understand if it's a real problem (that needs to be fixed by increasing a buffer size).

      I can verify that the "%.*g" formatting still works ok when the buffer size needs to be bigger than 127.
      For example, with this patched perl, perl -le 'printf "%.751g\n", 2 ** - 1074;' prints out all 751 mantissa digits correctly and displays the exact decimal rendition of the value 2 ** -1074.
      $ ./perl -I./lib -le 'printf "%.751g\n", 2 ** - 1074;' 4.94065... another 740 digits ...65625e-324

      Actually, I can add a little to that.
      I hacked the source to print out the size of the buffer, and I've just discovered that, so long as I ask for no more than 91 digits, the buffer size is 127 - which should be sufficient.
      But as soon as I ask for more than 91 digits, the buffer size is not displayed - indicating that the processing has switched to a different block.
      Incredibly, when I ask for more than 91 digits, I've also just now realized that the "%.*g" formatting works fine on Ubuntu-18.04 perls. That is, the bug exists only when I request 18 to 91 (inclusive) digits.
      If I request a number outside of that range, it works fine on a standard (unpatched) perl-5.32.0 on Ubuntu-18.04:
      $ perl -le 'printf "%.91g\n", 2 ** -1074;' 4.9406564584124654e-324 $ perl -le 'printf "%.92g\n", 2 ** -1074;' 4.94065645841246544176568792868221372365059802614324764425585682500675 +50727020875186529983636e-324
      So it looks to me that the concern surrounding the 127-byte buffer is unfounded, because the processing switches to a different block as soon as we ask for more than 91 digits.
      But I'm not prepared to claim that I've actually proved anything ;-)

      Cheers,
      Rob

        Ok, the main calculation in the perl source is I think this statement from sv.c:

        /* Determine the buffer size needed for the various * floating-point formats. * * The basic possibilities are: * * <---P---> * %f 1111111.123456789 * %e 1.111111123e+06 * %a 0x1.0f4471f9bp+20 * %g 1111111.12 * %g 1.11111112e+15 * * where P is the value of the precision in the format, or + 6 * if not specified. Note the two possible output formats +of * %g; in both cases the number of significant digits is < += * precision. * * For most of the format types the maximum buffer size ne +eded * is precision, plus: any leading 1 or 0x1, the radix * point, and an exponent. The difficult one is %f: for a * large positive exponent it can have many leading digits +, * which needs to be calculated specially. Also %a is slig +htly * different in that in the absence of a specified precisi +on, * it uses as many digits as necessary to distinguish * different values. * * First, here are the constant bits. For ease of calculat +ion * we over-estimate the needed buffer size, for example by * assuming all formats have an exponent and a leading 0x1 +. * * Also for production use, add a little extra overhead fo +r * safety's sake. Under debugging don't, as it means we're * more likely to quickly spot issues during development. */ float_need = 1 /* possible unary minus */ + 4 /* "0x1" plus very unlikely carry */ + 1 /* default radix point '.' */ + 2 /* "e-", "p+" etc */ + 6 /* exponent: up to 16383 (quad fp) */ #ifndef DEBUGGING + 20 /* safety net */ #endif + 1; /* \0 */

        .. after which if we are subject to locale it goes and checks the actual length of the utf8 representation of the radix point and adjusts that "+ 1" for the default. The above adds up to 35, which is pretty close to the difference between 91 and 127.

        The origin of the gcc warning looks like it might be gimple-ssa-sprintf.c or a close relative, in which case the "#define target_mb_len_max() 6" may well explain the difference between 127 and 133.

        So this looks pretty safe to me - and you'd certainly need a debugging perl to get close to exercising the limits.

        That just leaves the question of whether we can give the compiler enough hints for it to come to the same conclusion, or whether we'd only be able to shut it up with a sledgehammer preprocessor directive.

        Hugo

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11122370]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (6)
As of 2024-03-28 11:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found