ungetc and fseek/ftell cause segmentation bug
Stefan Sablatnög
Stefan.Sablatnoeg at gmx.de
Tue Jan 18 21:08:20 UTC 2011
Hi everybody,
I encounter a bug with ungetc on many different glibc system, though all are
ubuntu, at least debain I thought this place would be right.
My problem is a segmentation fault on fclose, that happens when I run the
following short test program. Assume a file named abc exists and it contains at
least 10 characters. ( I use Hello)
Here is the program:
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *file = fopen("abc", "rb");
if (0 != file)
{
int pos = 0;
int len = 0;
int value1;
pos = ftell(file);
if(-1 == pos)
{
return -1;
}
if(0 != fseek(file, 0, SEEK_END))
{
return -1;
}
len = ftell(file);
if(0 != fseek(file, pos, SEEK_SET))
{
return -1;
}
value1 = fgetc(file);
printf("%c\n",value1);
ungetc(value1, file);
value1 = fgetc(file);
printf("%c\n",value1);
ungetc('#', file);
value1 = fgetc(file);
printf("%c\n",value1);
ungetc('?', file);
fseek(file, 0, SEEK_SET);
value1 = fgetc(file);
printf("%c\n",value1);
fclose(file);
printf("OK\n");
}
}
So there is nothing very fancy, just some harmless file operations. What I
receive is:
stefan at pilch2:/tmp$ echo "Hello" >abc
stefan at pilch2:/tmp$ ./test_ungetc
H
H
#
e
*** glibc detected *** ./test_ungetc: free(): invalid pointer: 0xb787f000 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(+0x6b591)[0xb776f591]
/lib/tls/i686/cmov/libc.so.6(+0x6cde8)[0xb7770de8]
/lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0xb7773ecd]
/lib/tls/i686/cmov/libc.so.6(_IO_free_backup_area+0x34)[0xb776da34]
/lib/tls/i686/cmov/libc.so.6(_IO_unsave_markers+0x32)[0xb776d752]
/lib/tls/i686/cmov/libc.so.6(_IO_file_close_it+0x42)[0xb776c542]
/lib/tls/i686/cmov/libc.so.6(fclose+0x188)[0xb775fae8]
./test_ungetc[0x804872f]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xb771abd6]
./test_ungetc[0x80484e1]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:04 16975036 /tmp/test_ungetc
08049000-0804a000 r--p 00000000 08:04 16975036 /tmp/test_ungetc
0804a000-0804b000 rw-p 00001000 08:04 16975036 /tmp/test_ungetc
09f8e000-09faf000 rw-p 00000000 00:00 0 [heap]
b75bf000-b75dc000 r-xp 00000000 08:04 1387787 /lib/libgcc_s.so.1
b75dc000-b75dd000 r--p 0001c000 08:04 1387787 /lib/libgcc_s.so.1
b75dd000-b75de000 rw-p 0001d000 08:04 1387787 /lib/libgcc_s.so.1
b7600000-b7621000 rw-p 00000000 00:00 0
b7621000-b7700000 ---p 00000000 00:00 0
b7703000-b7704000 rw-p 00000000 00:00 0
b7704000-b7857000 r-xp 00000000 08:04 51428497
/lib/tls/i686/cmov/libc-2.11.1.so
b7857000-b7858000 ---p 00153000 08:04 51428497
/lib/tls/i686/cmov/libc-2.11.1.so
b7858000-b785a000 r--p 00153000 08:04 51428497
/lib/tls/i686/cmov/libc-2.11.1.so
b785a000-b785b000 rw-p 00155000 08:04 51428497
/lib/tls/i686/cmov/libc-2.11.1.so
b785b000-b785e000 rw-p 00000000 00:00 0
b787e000-b7882000 rw-p 00000000 00:00 0
b7882000-b7883000 r-xp 00000000 00:00 0 [vdso]
b7883000-b789e000 r-xp 00000000 08:04 3094462 /lib/ld-2.11.1.so
b789e000-b789f000 r--p 0001a000 08:04 3094462 /lib/ld-2.11.1.so
b789f000-b78a0000 rw-p 0001b000 08:04 3094462 /lib/ld-2.11.1.so
bf84c000-bf861000 rw-p 00000000 00:00 0 [stack]
Aborted
stefan at pilch2:/tmp$
Most annoying of course is the fact, that the call to fclose causes a crash.
Less problematic, but also wrong is the file position after the last fseek,
fseek is expected to throw away what was put back to the stream, but
it should position on the first letter (H) not on the 'e'.
I checked the following platforms:
ubuntu 10.04 desktop (including all updates up to January 18th 2011) 32bit
ubuntu 9.04 on arm
ubuntu on hppa
older debian on x86_64
older debian on sparc32
with glibc versions :
Version: 2.11.1-0ubuntu7.7 (x86 32 bit)
Version: 2.11.1-0ubuntu7.2 (x86 32 bit)
Version: 2.7-18 (x86_64)
Version: 2.10.1-0ubuntu15 (arm)
Version: 2.6.1-6ubuntu2 (hppa)
Version: 2.3.6.ds1-13etch10 (sparc32)
all these platforms show this behaviour. Unfortunately I do not have a system
with glibc version 2.12.2 which seems to be the latest one at the moment.
Is this a known Bug in glibc?
Is there a workaround?
Can the circumstances for it to happen be defined more precisely?
Should I submit this bug to glibc directly?
thanks in advance for your support!
--
Stefan
More information about the Ubuntu-devel-discuss
mailing list