Package: libc6
Version: 2.3.6-16
Severity: normal
Hello,
The following program prints "-1" rather than "5" on my laptop:
#include <stdio.h>
#include <limits.h>
int main()
{
char buf[256];
printf("%d\n", snprintf(buf, sizeof(buf), "%.2000000000s", "hello"));
return 0;
}
Here is the strace:
execve("/tmp/a.out", ["/tmp/a.out"], [/* 95 vars */]) = 0
uname({sys="Linux", node="ligate", ...}) = 0
brk(0) = 0x804a000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f5c000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f5b000
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=78547, ...}) = 0
mmap2(NULL, 78547, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f47000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/cmov/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\240O\1"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1241392, ...}) = 0
mmap2(NULL, 1247388, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7e16000
mmap2(0xb7f3d000, 28672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x127) = 0xb7f3d000
mmap2(0xb7f44000, 10396, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7f44000
close(3) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7e15000
mprotect(0xb7f3d000, 20480, PROT_READ) = 0
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7e156c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
munmap(0xb7f47000, 78547) = 0
mmap2(NULL, 2000003072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
brk(0) = 0x804a000
brk(0x7f3c4000) = 0x804a000
mmap2(NULL, 2000134144, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
mmap2(NULL, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0xb7c15000
munmap(0xb7c15000, 962560) = 0
munmap(0xb7e00000, 86016) = 0
mprotect(0xb7d00000, 135168, PROT_READ|PROT_WRITE) = 0
mmap2(NULL, 2000003072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
fstat64(1, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfa70118) = -1 ENOTTY (Inappropriate ioctl for device)
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f5a000
write(1, "-1\n", 3) = 3
munmap(0xb7f5a000, 4096) = 0
exit_group(0) = ?
Process 6984 detached
The same program correctly prints "5" on my desktop, and here is the
strace:
execve("./a.out", ["./a.out"], [/* 91 vars */]) = 0
uname({sys="Linux", node="reincarnation", ...}) = 0
brk(0) = 0x804a000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f80000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=84156, ...}) = 0
mmap2(NULL, 84156, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f6b000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/cmov/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\240O\1"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1241392, ...}) = 0
mmap2(NULL, 1247388, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7e3a000
mmap2(0xb7f61000, 28672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x127) = 0xb7f61000
mmap2(0xb7f68000, 10396, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7f68000
close(3) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7e39000
mprotect(0xb7f61000, 20480, PROT_READ) = 0
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7e398e0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
munmap(0xb7f6b000, 84156) = 0
mmap2(NULL, 2000003072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40adf000
munmap(0x40adf000, 2000003072) = 0
fstat64(1, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbf892e80) = -1 ENOTTY (Inappropriate ioctl for device)
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f7f000
write(1, "5\n", 2) = 2
munmap(0xb7f7f000, 4096) = 0
exit_group(0) = ?
Process 5022 detached
The difference seems to be whether the call to mmap2 after the
call to set_thread_area succeeds. It seems that glibc is trying
to allocate almost 2G of memory in order to print into a 256-byte
buffer, and there is not enough address space for the allocation.
(My laptop kernel (custom 2.6.16) config sets CONFIG_NOHIGHMEM=y and
CONFIG_VMSPLIT_3G=y, whereas my desktop kernel (another custom 2.6.16)
sets CONFIG_HIGHMEM4G=y and CONFIG_VMSPLIT_3G=y.)
Thanks,
Ken
-- System Information:
Debian Release: testing/unstable
APT prefers unstable
APT policy: (500, 'unstable'), (500, 'testing')
Architecture: i386 (i686)
Shell: /bin/sh linked to /bin/bash
Kernel: Linux 2.6.16
Locale: LANG=zh_TW.UTF-8, LC_CTYPE=zh_TW.UTF-8 (charmap=UTF-8)
Versions of packages libc6 depends on:
ii tzdata 2006g-2 Time Zone and Daylight Saving Time
libc6 recommends no packages.
-- no debconf information
--
Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig
I find it funny how the more interesting something is to me
the harder it is for me to think of a use for it. -- A post on Ars Technica
Attachment:
signature.asc
Description: Digital signature