develooper Front page | perl.perl5.porters | Postings from January 2019

[perl #133495] perl-5.28.0 fails to build on Solaris 10

Thread Next
From:
Fabian Groffen via RT
Date:
January 19, 2019 03:23
Subject:
[perl #133495] perl-5.28.0 fails to build on Solaris 10
Message ID:
rt-4.0.24-2611-1547713575-311.133495-15-0@perl.org
On Wed, 16 Jan 2019 18:34:24 -0800, LeonT wrote:
> On Wed, Jan 16, 2019 at 3:47 PM Fabian Groffen via RT
> > This is obviously wrong on sparc.  The check also fails on 5.26.2 but
> > for some reason no bus-error there.  I manually set d_u32align and
> > that made the 5.28.0 build succeed.
> 
> That is most helpful. That macro has two implementations, one for
> platforms little endian platforms without alignment requirement and
> one for platforms with requirements. It clearly picks the wrong
> options here.
> 
> It's not just that, it picks the wrong one (the aligned version) on
> x64 as well. This appears to be caused by not taking into account
> 64bitness. That doesn't explain why it thinks it can access those
> bytes unalignedly on SPARC though. Could an overeager optimizer cause
> it not to fail? What is the autodetected value of d_u32align when it
> does work?

I think that the GCC compiler is actually doing "too smart" things here when optimisations are enabled.

I extracted the code it tries:

% cat unaligned.c 
#include <stdio.h>
#define I_STDLIB
#ifdef I_STDLIB
#include <stdlib.h>
#endif
#define U32 unsigned long
#define BYTEORDER 0x4321
#define U8 unsigned char
#include <signal.h>
#ifdef SIGBUS
void bletch(int s) { exit(4); }
#endif
int main() {
#if BYTEORDER == 0x1234 || BYTEORDER == 0x4321
    volatile U8 buf[8];
    volatile U32 *up;
    int i;

    if (sizeof(U32) != 4) {
        printf("sizeof(U32) is not 4, but %d\n", sizeof(U32));
        exit(1);
    }

    fflush(stdout);

#ifdef SIGBUS
    signal(SIGBUS, bletch);
#endif

    buf[0] = 0;
    buf[1] = 0;
    buf[2] = 0;
    buf[3] = 1;
    buf[4] = 0;
    buf[5] = 0;
    buf[6] = 0;
    buf[7] = 1;

    for (i = 0; i < 4; i++) {
        up = (U32*)(buf + i);
        if (! ((*up == 1 << (8*i)) ||   /* big-endian */
               (*up == 1 << (8*(3-i)))  /* little-endian */
              )
           )
        {
            printf("read failed (%x)\n", *up);
            exit(2);
        }
    }

    /* write test */
    for (i = 0; i < 4; i++) {
        up = (U32*)(buf + i);
        *up = 0xBeef;
        if (*up != 0xBeef) {
            printf("write failed (%x)\n", *up);
            exit(3);
        }
    }

    exit(0);
#else
    printf("1\n");
    exit(1);
#endif
    return 0;
}

Next, I compile and run this example like Configure does:

$ for flag in "-O2" "-g" ; do for cc in /usr/sfw/bin/gcc gcc-6.4.0 gcc-7.3.0 gcc-8.2.0 ; do $cc --version ; $cc $flag -o unaligned unaligned.c ; ./unaligned ; echo "$cc $flag -> $?" ; done ; done
gcc (GCC) 3.4.3 (csl-sol210-3_4-branch+sol_rpath)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

/usr/sfw/bin/gcc -O2 -> 4
gcc-6.4.0 (Gentoo 6.4.0-r2 p1.4) 6.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

unaligned.c: In function ‘main’:
unaligned.c:46:28: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
      printf("read failed (%x)\n", *up);
                            ^
unaligned.c:56:29: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
      printf("write failed (%x)\n", *up);
                             ^
gcc-6.4.0 -O2 -> 4
gcc-7.3.0 (Gentoo 7.3.0-r3 p1.4) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

unaligned.c: In function ‘main’:
unaligned.c:46:28: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
      printf("read failed (%x)\n", *up);
                           ~^      ~~~
                           %lx
unaligned.c:56:29: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
      printf("write failed (%x)\n", *up);
                            ~^      ~~~
                            %lx
gcc-7.3.0 -O2 -> 4
gcc-8.2.0 (Gentoo 8.2.0-r5 p1.6) 8.2.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

unaligned.c: In function ‘main’:
unaligned.c:46:28: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
      printf("read failed (%x)\n", *up);
                           ~^      ~~~
                           %lx
unaligned.c:56:29: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
      printf("write failed (%x)\n", *up);
                            ~^      ~~~
                            %lx
gcc-8.2.0 -O2 -> 0
gcc (GCC) 3.4.3 (csl-sol210-3_4-branch+sol_rpath)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

/usr/sfw/bin/gcc -g -> 4
gcc-6.4.0 (Gentoo 6.4.0-r2 p1.4) 6.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

unaligned.c: In function ‘main’:
unaligned.c:46:28: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
      printf("read failed (%x)\n", *up);
                            ^
unaligned.c:56:29: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
      printf("write failed (%x)\n", *up);
                             ^
gcc-6.4.0 -g -> 4
gcc-7.3.0 (Gentoo 7.3.0-r3 p1.4) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

unaligned.c: In function ‘main’:
unaligned.c:46:28: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
      printf("read failed (%x)\n", *up);
                           ~^      ~~~
                           %lx
unaligned.c:56:29: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
      printf("write failed (%x)\n", *up);
                            ~^      ~~~
                            %lx
gcc-7.3.0 -g -> 4
gcc-8.2.0 (Gentoo 8.2.0-r5 p1.6) 8.2.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

unaligned.c: In function ‘main’:
unaligned.c:46:28: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
      printf("read failed (%x)\n", *up);
                           ~^      ~~~
                           %lx
unaligned.c:56:29: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
      printf("write failed (%x)\n", *up);
                            ~^      ~~~
                            %lx
gcc-8.2.0 -g -> 4


So, basically above list without the barf:

/usr/sfw/bin/gcc -O2 -> 4
gcc-6.4.0 -O2 -> 4
gcc-7.3.0 -O2 -> 4
gcc-8.2.0 -O2 -> 0
/usr/sfw/bin/gcc -g -> 4
gcc-6.4.0 -g -> 4
gcc-7.3.0 -g -> 4
gcc-8.2.0 -g -> 4

Behaviour seems to be pretty much limited to gcc-8.2 while optimising at the moment.

> Yves added some hashing code in 5.27 that made usage of this macro,
> AFAICT it wasn't used anywhere except in an optimization in
> Digest::MD5. I guess that's why we never noticed something was broken
> about it.

Yes, including the fact that at the time I compiled 5.26.2, I used GCC-7.3, which produced the correct result for the unaligned check.

This makes me wonder what the problem of OP is, though.  His env seems to suggest using GCC-4.9, which I don't have anymore for verification of the results.


---
via perlbug:  queue: perl5 status: open
https://rt.perl.org/Ticket/Display.html?id=133495

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About