Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 17 Jul 2016 00:58:52 +0000
From:      bugzilla-noreply@freebsd.org
To:        freebsd-ports-bugs@FreeBSD.org
Subject:   [Bug 211152] benchmarks/iozone: Build fails on typedef redefinition with different types ('long long' vs '__off64_t' (aka 'long'))
Message-ID:  <bug-211152-13-qWkwDqEG3k@https.bugs.freebsd.org/bugzilla/>
In-Reply-To: <bug-211152-13@https.bugs.freebsd.org/bugzilla/>
References:  <bug-211152-13@https.bugs.freebsd.org/bugzilla/>

next in thread | previous in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D211152

--- Comment #11 from Mark Millard <markmi@dsl-only.net> ---
(In reply to w.schwarzenfeld from comment #10)

I do not have a FreeBSD 10.x or earlier context to check. So I've not teste=
d if
the "delete line" issue is 11.0+ specific or not. My guess is that it is no=
t.
So the version test may be wrong.

The following would cause the Makefile to be very fragile relative to iozon=
e.c
updates: nothing checks that the correct line is being deleted or reports w=
hen
things have likely changed. It is now commented for the issue but. . .

.if ${OPSYS} =3D=3D FreeBSD && ${OSVERSION} >=3D 1100000
        @${REINPLACE_CMD} -e '363d' ${WRKSRC}/iozone.c
.endif

usually C source code checks its own context via macro tests. Why adjust the
Makefile instead of iozone.c itself?

Looking around shows iozone has no explicit support for 64-bit for freebsd:

/usr/ports/benchmarks/iozone/Makefile has:

MAKEFILE=3D       makefile
MAKE_ARGS=3D      ${MAKE_ENV}
ALL_TARGET=3D     freebsd

which uses:

. . ./iozone3_434/src/current/makefile

# grep -i freebsd
/usr/obj/portswork/usr/ports/benchmarks/iozone/work/iozone3_434/src/current=
/makefile
#               convex, FreeBSD, OpenBSD, OSFV3, OSFV4, OSFV5, SCO
        @echo "        ->   freebsd              (32bit)   <-"
# GNU C compiler FreeBSD build with no threads, no largefiles, no async I/O
freebsd:        iozone_freebsd.o libbif.o fileop_freebsd.o libasync.o
pit_server.o
        $(CC) $(LDFLAGS) iozone_freebsd.o libbif.o -lpthread libasync.o \
        $(CC)  -O fileop_freebsd.o -o fileop
fileop_freebsd.o:       fileop.c
        @echo "Building fileop for FreeBSD"
        $(CC) -c -O $(CFLAGS) fileop.c -o fileop_freebsd.o
iozone_freebsd.o:       iozone.c libbif.c libasync.c
        @echo "Build iozone for FreeBSD"
        $(CC) -c ${CFLAGS}  -DFreeBSD -Dunix -Dbsd4_4 -DHAVE_ANSIC_C -DASYN=
C_IO
\
                -DHAVE_PREAD -DNAME=3D'"freebsd"' -DSHARED_MEM \
                $(CFLAGS) iozone.c -o iozone_freebsd.o
        $(CC) -c ${CFLAGS} -DFreeBSD -Dunix -Dbsd4_4 -DHAVE_ANSIC_C -DASYNC=
_IO
\
        $(CC) -c ${CFLAGS} -DFreeBSD -Dunix -Dbsd4_4 -DHAVE_ANSIC_C -DASYNC=
_IO
\

The the types that should be involved likely change for:

TARGET_ARCH=3Damd64 or powerpc64 or aarch64
vs.
TARGET_ARCH=3Di386 or powerpc or armv6

(not a comprehensive list).

So LP64 vs. ILP32, little endian vs. big endian, possibly alignment. FreeBSD
has a wide range. (I currently have access only to examples of amd64 and
armv6.)

Looking around NO_PRINT_LLD is not defined for freebsd:

# grep -i NO_PRINT_
/usr/obj/portswork/usr/ports/benchmarks/iozone/work/iozone3_434/src/current=
/makefile
                -DNAME=3D'"OSFV3"' -DNO_PRINT_LLD -DOSF_64 $(CFLAGS) iozone=
.c \
                -DNO_PRINT_LLD  -DOSF_64 $(CFLAGS) libbif.c -o libbif.o
                -DNO_PRINT_LLD -DOSF_64 $(CFLAGS) libasync.c -o libasync.o
                -DNAME=3D'"OSFV4"' -DNO_PRINT_LLD -DOSF_64 $(CFLAGS) iozone=
.c \
                -DNO_PRINT_LLD  -DOSF_64 $(CFLAGS) libbif.c -o libbif.o
                -DNO_PRINT_LLD -DOSF_64 $(CFLAGS) libasync.c -o libasync.o
                -DNAME=3D'"OSFV5"' -DNO_PRINT_LLD -DOSF_64 $(CFLAGS) iozone=
.c \
                -DNO_PRINT_LLD  -DOSF_64 $(CFLAGS) libbif.c -o libbif.o
                -DNO_PRINT_LLD -DOSF_64 $(CFLAGS) libasync.c -o libasync.o
                -DNAME=3D'"TRU64"' -DNO_PRINT_LLD -DOSF_64 -pthread $(CFLAG=
S)
iozone.c \
                -DNO_PRINT_LLD  -DOSF_64 $(CFLAGS) libbif.c -o libbif.o
                -DNO_PRINT_LLD -DOSF_64 $(CFLAGS) libasync.c -o libasync.o

So only OSF_64 variants involve NO_PRINT_LLD being defined. So it appears a
bunch of changes are irrelevant to FreeBSD but might be important for
non-FreeBSD. I've not tried anything under non-FreeBSD.

Ignoring that for the moment relative to FreeBSD, take the example:

 #ifdef NO_PRINT_LLD
-                       sscanf(optarg,"%ld",&kilobytes64);
+                       sscanf(optarg,"%ld",(long long *)&kilobytes64);

%ld is not a long long format. It is a long int format. For ILP32 contexts =
long
int and long long are not sized the same. There may not be examples yet but=
 for
LP64 long long could be more than 64-bits instead of matching long int's si=
ze.

Changing the type of the pointer where the value is to be stored is general=
ly
dangerous. The format must match the actual storage layout involved (includ=
ing
size, alignment). Mismatched type sizes between the format and the storage =
can
get into endianness handling problems (format too small for the storage),
truncation problems (format too small for the storage), memory overwrite
problems (format too big for the storage). There could be alignment issues =
as
well.

For the variations of scan: Having "full/larger-than-needed width" in the
target type locally and then validating the values would fit in the desired
final storage and then converting if things are okay would be more generic =
to
variations like LP64 vs. IPL32 and such.

As for the printf variations:

+ #ifdef NO_PRINT_LLD
+-                      sprintf(splash[splash_line++],"\tUsing minimum file
size of %ld kilobytes.\n",minimum_file_size);
++                      sprintf(splash[splash_line++],"\tUsing minimum file
size of %ld (long long)kilobytes.\n",minimum_file_size);

This example added a "(long long)" to the string text. Why?

+ #ifdef NO_PRINT_LLD
+-                      sprintf(splash[splash_line++],"\tFile size set to %=
ld
kB\n",kilobytes64);
++                      sprintf(splash[splash_line++],"\tFile size set to %=
ld
kB\n",(long long )kilobytes64);

%ld is not a long long format. It is a long int format. For ILP32 contexts =
long
int and long long are not sized the same. There may not be examples yet but=
 for
LP64 long long could be more than 64-bits instead of matching long int's si=
ze.

Incorrect value displays can happen when formats to not match storage layou=
ts.
Endianness handling problems (format too small for the storage), truncation
problems (format too small for the storage), memory access problems (format=
 too
big for the storage). There could be alignment issues as well.


It appears to me the the scan code with %lld (a long long format) might also
have some of these sorts of issues for various TARGET_ARCH's. The prints wi=
th
%lld and a matching (long long) cast for the value likely survive until lon=
g or
int happens to be be bigger than 64 bits.

(I've not looked for signed vs. unsigned issues.)

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-211152-13-qWkwDqEG3k>