[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#34953: The elm problem



Package: libc6
Version: 2.1.1-0.1
Severity: important

I've spent the day figuring out what goes wrong with a glib2.0-compiled
elm on a glibc2.1 system.  I didn't find the bug, but I managed to
distill a simple test case:

#include <stdio.h>

void bail(char *where) {
    perror(where);
    exit(1);
}

int main(void) {
    FILE *test;

    if ((test = fopen("seektestfile", "w+")) == NULL)  bail("fopen");
    if (fputs("Test data", test) < 0)  bail("fputs");
    if (fseek(test, 0, 2) != 0)  bail("fseek 1");
    if (fseek(test, 0, 0) != 0)  bail("fseek 2");
    if (fflush(test) != 0)  bail("fflush");
    exit(0);
}

If this program is compiled on a glibc2.0 system and run on a glibc2.1
system, the fflush call will fail with EINVAL.  If the program is
compiled on a glibc2.1 system and run on a glibc2.1 system, it works
fine.  The reason can be found in the relevant part of the straces.

Trace of glibc2.1-compiled (good) version:
[...]
open("seektestfile", O_RDWR|O_CREAT|O_TRUNC, 0666) = 4
fstat(4, {st_mode=S_ISVTX|0502, st_size=0, ...}) = 0
mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40014000
write(4, "Test data", 9)                = 9
fstat(4, {st_mode=S_ISVTX|0502, st_size=0, ...}) = 0
_llseek(4, 0, {0}, SEEK_SET)            = 0
read(4, "Test data", 4096)              = 9
_llseek(4, 9, {9}, SEEK_SET)            = 0
_llseek(4, -9, {0}, SEEK_CUR)           = 0
[...]

Trace of glibc2.0-compiled version:
[...]
open("seektestfile", O_RDWR|O_CREAT|O_TRUNC, 0666) = 4
fstat(4, {st_mode=S_ISVTX|0502, st_size=0, ...}) = 0
mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x400140
00
write(4, "Test data", 9)                = 9
fstat(4, {st_mode=S_ISVTX|0502, st_size=0, ...}) = 0
_llseek(4, 0, {0}, SEEK_SET)            = 0
read(4, "Test data", 4096)              = 9
_llseek(4, 9, {9}, SEEK_SET)            = 0
_llseek(4, 4294967287, 0xbffff9e8, SEEK_CUR) = -1 EINVAL (Invalid argument)

In both cases the final line is from fflush (not from fseek, which simply
sets some pointers and does not invoke a system call).  The number
4294967287 is exactly -9 when interpreted as an unsigned long, so
I expect that the problem is somewhere in the big-files handling.

I failed to track the problem down inside glibc, but I hope that this
test case helps.

Richard Braakman


Reply to: