assertion failure in snprntffuns.c:79 for i686-w64-mingw32
Vincent Lefevre
vincent at vinc17.net
Fri Jan 10 13:12:01 UTC 2020
On 2020-01-10 08:44:13 +0100, Niels Möller wrote:
> Vincent Lefevre <vincent at vinc17.net> writes:
>
> > Under Debian/unstable, I've configured GMP with:
> >
> > ./configure --host=i686-w64-mingw32 --disable-shared --enable-assert
> >
> > but "make check LOG_COMPILER=wine" gives:
> >
> > FAIL: t-printf
> > ==============
> >
> > snprntffuns.c:79: GNU MP assertion failed: strlen (d->buf) == avail-1
> > FAIL t-printf.exe (exit status: 3)
> >
> > The failing code is
> >
> > ret = vsnprintf (d->buf, avail, fmt, ap);
> > if (ret == -1)
> > {
> > ASSERT (strlen (d->buf) == avail-1);
> > ret = avail-1;
> > }
>
> Does it make a difference if you add CPPFLAGS=-D__USE_MINGW_ANSI_STDIO
> to the configuration?
I get no failures.
> > I don't understand the ASSERT. A return value of -1 means an output
> > error, so that you cannnot deduce anything about the contents stored
> > in d->buf.
>
> Non-standard versions of snprintf returned -1 for truncation (including
> old glibc, and likely windows libc too). And the way I read the ASSERT,
> it says that truncation is the only expected reason for vsnprintf to
> return -1. What was fmt? It would be helpful to understand the reason
> for the -1 return in the failing case.
Here's what I get for i = 3 to 7:
i = 3, limb = 7 (1)
avail = 2, fmt = "%lu", ret = 1, buf = "7"
i = 4, limb = 15 (1)
avail = 2, fmt = "%lu", ret = 2, buf = "15!"
i = 5, limb = 31 (1)
avail = 2, fmt = "%lu", ret = 2, buf = "31!"
i = 6, limb = 63 (1)
avail = 2, fmt = "%lu", ret = 2, buf = "63!"
i = 7, limb = 127 (1)
avail = 2, fmt = "%lu", ret = -1, buf = "12!7"
So, one gets a truncation because avail = 2 is too small for 127,
and like with old glibc, one gets ret = -1. GMP expects that a \0
at the end is written in this case, and perhaps old glibc did, but
not mingw.
Note that the "7" after the sentinel is just old data. If I add
d->buf[avail+1] = '\0';
before the
ret = vsnprintf (d->buf, avail, fmt, ap);
I get:
avail = 2, fmt = "%lu", ret = -1, buf = "12!"
So, without -D__USE_MINGW_ANSI_STDIO, this is non-conforming (perhaps
for compatibility if vsnprintf was implemented in MS Windows before
it got standardized in ISO C99). I think that a fix should be easy:
write a \0 before the sentinel, and if ret = -1 and this \0 has been
replaced by vsnprintf, this probably means truncation.
--
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