not really a bug but somewhat odd : checking compiler /usr/local/bin/gcc8 ... no, mpn_lshift_com

Vincent Lefevre vincent at vinc17.net
Sun Jul 28 12:09:50 UTC 2019


On 2019-07-28 07:40:38 -0400, Dennis Clarke wrote:
> On 7/28/19 7:32 AM, Vincent Lefevre wrote:
> > On 2019-07-28 12:44:55 +0200, Vincent Lefevre wrote:
> >> On 2019-07-28 06:12:06 -0400, Dennis Clarke wrote:
> >>> configure:6813: ./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest
> >>> Abort trap (core dumped)
> >>
> >> I don't know in your case, but I fear that this program is buggy.
> > [...]
> > 
> > You can try the attached patch in case this would be the issue.
> > This could also solve invisible failures (as occurring inside
> > configure) in other cases.
> > 
> 
> Thank you for that but I suspect the problem lay entirely elsewhere in
> an unexpected place :

I don't see how you can deduce that.

The error occurs at:

> #2  0x00000008101cf41c in abort () from /lib/libc.so.7
> #3  0x0000000010000cb4 in main () at foo.c:51

Thus in the program

> hydra$ cat foo.c
> 
> /* The following is mis-compiled by Intel ia-64 icc version 1.8 under
>     "icc -O3",  After several calls, the function writes partial garbage to
>     the result vector.  Perhaps relates to the chk.a.nc insn.  This code
> needs
>     to be run to show the problem, but that's fine, the offending cc is a
>     native-only compiler so we don't have to worry about cross
> compiling.  */
> 
> #if ! defined (__cplusplus)
> #include <stdlib.h>
> 
> void lshift_com (rp, up, n, cnt)
>   unsigned long *rp;
>   unsigned long *up;
>   long n;
>   unsigned cnt;
> {
>   unsigned long high_limb, low_limb;
>   unsigned tnc;
>   long i;
>   up += n;
>   rp += n;
>   tnc = 8 * sizeof (unsigned long) - cnt;
>   low_limb = *--up;
>   high_limb = low_limb << cnt;
>   for (i = n - 1; i != 0; i--)
>     {
>       low_limb = *--up;
>       *--rp = ~(high_limb | (low_limb >> tnc));
>       high_limb = low_limb << cnt;
>     }
>   *--rp = ~high_limb;
> }
> 
> int main () {
>   unsigned long *r, *r2;
>   unsigned long a[88 + 1];
>   long i;
>   for (i = 0; i < 88 + 1; i++)
>     a[i] = ~0L;
>   r = malloc (10000 * sizeof (unsigned long));
>   r2 = r;
>   for (i = 0; i < 528; i += 23)
>     {
>       lshift_com (r2, a,
>                   i / (8 * sizeof (unsigned long)) + 1,
>                   i % (8 * sizeof (unsigned long)));
>       r2 += 88 + 1;
>     }
>   if (r[2048] != 0 || r[2049] != 0 || r[2050] != 0 || r[2051] != 0 ||
>       r[2052] != 0 || r[2053] != 0 || r[2054] != 0)
>     abort ();

It is this abort that has been called, i.e. the memory does not contain
what is expected. An incorrect type sent to lshift_com due to missing
prototype (as with K&R function definition) could perfectly yield this
kind of problem.

>   free (r);
>   return 0;
> }
> 
> #else
> 
> int main () {
>   return 0;
> }
> 
> #endif
> 
> hydra$
> 
> 
> That compiles and runs fine on FreeBSD x86_64 with gcc 8.3.0 however on
>  the ppc64 boxen :
[...]
> (gdb) run
> Starting program:
> /opt/bw/build/gmp-6.1.2_FreeBSD_13.0-CURRENT_r350103_ppc64.001/foo
> 
> Program received signal SIGABRT, Aborted.
> 0x000000081026b898 in .__sys_thr_kill () from /lib/libc.so.7
> (gdb) bt
> #0  0x000000081026b898 in .__sys_thr_kill () from /lib/libc.so.7
> #1  0x000000081026af3c in .__raise () from /lib/libc.so.7
> #2  0x00000008101cf41c in abort () from /lib/libc.so.7
> #3  0x0000000010000cb4 in main () at foo.c:51
> (gdb) quit
> A debugging session is active.
> 
>         Inferior 1 [process 3361] will be killed.
> 
> Quit anyway? (y or n) y
> hydra$
> 
> Well looks to be in libc.so.7 here.   :-(

libc.so.7 behaves as expected: an abort has been called in foo.c,
thus the library aborts the program.

-- 
Vincent Lefèvre <vincent at vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)


More information about the gmp-bugs mailing list