bug-gnulib
[Top][All Lists]
Advanced

[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.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]