[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
uh oh: when to use the xprintf module
From: |
Jim Meyering |
Subject: |
uh oh: when to use the xprintf module |
Date: |
Sat, 03 Nov 2007 00:23:16 +0100 |
Unfortunately, you may well have to use xprintf much more generally,
(or else check all *printf return values) if you care about robustness
under low-memory conditions.
This is because the printf, fputs, fwrite, etc. functions
(at least glibc-based functions) always allocate memory upon
stream initialization. The first output appears to cause allocation
of a 4KB block (a page). I want to know if that first stream output
operation can fail without setting the stream error indicator.
I tried to provoke this, to see if a failure of that precise allocation
would provoke an ferror-detectable failure, but ran into something else.
When that particular mmap call fails (I think it's the one in
filedoalloc.c from the ALLOC_BUF macro), it ends up causing
a segfault 5 or 6 levels up the stack:
$ printf '#include <stdio.h>\nint main(){printf("foo");return 0;}\n' > k.c
$ gcc -g -Wall -W -O k.c
$ gdb -q ./a.out
Using host libthread_db library "/lib64/libthread_db.so.1".
(gdb) b printf
Function "printf" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (printf) pending.
(gdb) r
Starting program: /t/a/a.out
Breakpoint 2 at 0x3c5084ca00
Pending breakpoint "printf" resolved
Breakpoint 2, 0x0000003c5084ca00 in printf () from /lib64/libc.so.6
(gdb) b mmap64
Breakpoint 3 at 0x3c508d18d0
(gdb) c
Continuing.
Breakpoint 3, 0x0000003c508d18d0 in mmap64 () from /lib64/libc.so.6
(gdb) ret -1
Make selected stack frame return now? (y or n) y
#0 0x0000003c508613db in _IO_file_doallocate_internal () from
/lib64/libc.so.6
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x0000003c5086c8dc in _IO_new_file_overflow () from /lib64/libc.so.6
(gdb) bt
#0 0x0000003c5086c8dc in _IO_new_file_overflow () from /lib64/libc.so.6
#1 0x0000003c5086ec34 in _IO_default_xsputn_internal () from /lib64/libc.so.6
#2 0x0000003c5086d881 in _IO_new_file_xsputn () from /lib64/libc.so.6
#3 0x0000003c50842f50 in vfprintf () from /lib64/libc.so.6
#4 0x0000003c5084ca9a in printf () from /lib64/libc.so.6
#5 0x00000000004004cb in main () at k.c:2
(gdb)
This is not totally fair, because while I made mmap64 return -1,
I did not set errno, which would normally happen for a real failure.
I tried, but __errno_location() returns an invalid address.
Anyone know how to set errno via gdb?
Same thing happened when I compiled with -ggdb3.
This is on fedora rawhide, but I got a segfault on debian unstable, too.
- uh oh: when to use the xprintf module,
Jim Meyering <=