Red Hat Bugzilla – Bug 456888
fflush on wide-oriented stream segfaults in some locale
Last modified: 2008-07-29 12:38:00 EDT
Description of problem:
The "fflush" function seems to involve an invalid memory use.
If it is called with a wide-character oriented stream as the argument,
it may result in a segmentation fault or an infinite loop.
This occurs when the stream is open for reading a regular file (not
a terminal or a pipe).
The gdb debugger says that the stack is corrupted when I interrupt the
program in the infinite loop.
Version-Release number of selected component (if applicable):
reproducible with glibc-2.8-8 (i686) on fedora 9
always, at least on the condition described below.
The behavior differs depending on the locale and the input text.
Steps to Reproduce:
$ cat flushbug.c
#define _POSIX_C_SOURCE 200112L
fgetws(buf, 1000, stdin);
execlp("cat", "cat", (const char *) NULL);
$ cat flushbug.txt.en
$ gcc -std=c99 -ggdb -o flushbug flushbug.c
$ LC_ALL=C ./flushbug <flushbug.txt.en
$ LC_ALL=ja_JP.utf8 ./flushbug <flushbug.txt.en
Segmentation fault (core dumped)
The output of "LC_ALL=C ./flushbug <flushbug.txt.en" is the desired result.
The first line of the input file is consumed by the "flushbug" program and
the remaining lines are read and output by "cat".
A call to "fflush" is required to ensure that the input file is re-seeked
so that the "cat" program reads the second and following lines.
Without "fflush", more than one lines might be consumed by the buffering in
the "flushbug" program.
The test case works well in some locales and does not in others.
Locales that work includes C, en_US.iso88591, de_DE.iso885915@euro.
Locales that does not work includes en_US.utf8, de_DE.utf8, ja_JP.eucjp.
The core dump of the test case above is attached.
Created attachment 312777 [details]
the core dump of the test case
The test program writes an uninitialized data region. That's of course not
valid and a crash is a perfectly fine response. Provide a correct program which
(In reply to comment #2)
Do you mean we need something like "wmemset(buf, 0, 1000)" before calling wgetws?
The program is reading from stdin by wgetws, not writing, so we do not have to initialize
the buffer, I believe.
I misread the program. Indeed, you don't have to clear the memory.
But now I can tell you that the program is outright wrong. fflush is not
defined on input stream.