testcase: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <wchar.h> #include <error.h> int main(int argc, char **argv) { char name[] = "/tmp/wprintf.out.XXXXXX"; int fd; FILE *fp; fd = mkstemp (name); fp = fdopen (dup (fd), "a"); if (fp == NULL) error (EXIT_FAILURE, errno, "fdopen(,\"a\")"); setvbuf (fp, NULL, _IONBF, 0); fwprintf (fp, L"hello.\n"); fclose (fp); return EXIT_SUCCESS; } strace of the testcase: getpid() = 10951 open("/tmp/wprintf.out.dr4WZ4", O_RDWR|O_CREAT|O_EXCL, 0600) = 3 dup(3) = 4 fcntl(4, F_GETFL) = 0x8002 (flags O_RDWR|O_LARGEFILE) fcntl(4, F_SETFL, O_RDWR|O_APPEND|O_LARGEFILE) = 0 brk(0) = 0x601000 brk(0x622000) = 0x622000 fstat(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b15e8210000 lseek(4, 0, SEEK_CUR) = 0 munmap(0x2b15e8210000, 4096) = 0 lseek(4, 0, SEEK_CUR) = 0 write(4, "h", 1) = 1 write(4, "e", 1) = 1 write(4, "l", 1) = 1 write(4, "l", 1) = 1 write(4, "o", 1) = 1 write(4, ".", 1) = 1 write(4, "\n", 1) = 1 close(4) = 0 munmap(0x601093, 4096) = -1 EINVAL (Invalid argument) note the -EINVAL part of /proc/self/maps: 00400000-00401000 r-xp 00000000 fd:00 3414911 /tmp/a.out 00600000-00601000 rw-p 00000000 fd:00 3414911 /tmp/a.out 00601000-00622000 rw-p 00601000 00:00 0 [heap] 38e2200000-38e221a000 r-xp 00000000 fd:00 7372823 /lib64/ld-2.5.so 38e2419000-38e241a000 r--p 00019000 fd:00 7372823 /lib64/ld-2.5.so and see how 0x601093 is in the heap. The testcase is lucky that it's not page-aligned and the kernel decides to -EINVAL it... otherwise glibc would have done... interesting things to the heap.
Well, it will never be page aligned, unless you have 1 byte pages. Anyway, worth fixing...
Should be fixed in glibc-2.5.90-13.