[uClibc 0002714]: sprintf should not pull in most of stdio.h code

bugs at busybox.net bugs at busybox.net
Wed Apr 9 00:54:30 UTC 2008


A NOTE has been added to this issue. 
====================================================================== 
http://busybox.net/bugs/view.php?id=2714 
====================================================================== 
Reported By:                vda
Assigned To:                uClibc
====================================================================== 
Project:                    uClibc
Issue ID:                   2714
Category:                   Stdio
Reproducibility:            always
Severity:                   minor
Priority:                   normal
Status:                     assigned
====================================================================== 
Date Submitted:             04-01-2008 09:26 PDT
Last Modified:              04-08-2008 17:54 PDT
====================================================================== 
Summary:                    sprintf should not pull in most of stdio.h code
Description: 
Use of [v]s[n]printf functions does not require application to necessarily
pull in the whole of stdio.h machinery. Only formatting routines are
needed.

Currently I observe +12k growth when I add a sprintf(dummy_buf, "%d",
some_var) to the program which otherwise does not use stdio.h. For one,
seek and write functions ideally should not appear.
====================================================================== 

---------------------------------------------------------------------- 
 vda - 04-01-08 11:13  
---------------------------------------------------------------------- 
Since I have a good test case, I can provide more info (link map rules!).
seeks are pulled in because of __UCLIBC_HAS_STDIO_AUTO_RW_TRANSITION__
here:

#ifdef __UCLIBC_HAS_WCHAR__
int attribute_hidden __stdio_trans2w_o(FILE * __restrict stream, int
oflag)
#else
int attribute_hidden __stdio_trans2w(FILE * __restrict stream)
#endif
{
...
        if (__STDIO_STREAM_IS_READING(stream)) {
                if (!__FEOF_UNLOCKED(stream)) {
#ifdef __UCLIBC_HAS_STDIO_AUTO_RW_TRANSITION__
                        /* Need to seek to correct position if we have
buffered
                         * read data or ungots.  If appending, we might as
well
                         * seek to the end.
                         *
                         * NOTE: If the OS does not handle append files
correctly,
                         *   this is insufficient since we would need to
seek to
                         *   the end even if not reading.*/
                        if (((__STDIO_STREAM_BUFFER_RAVAIL(stream))
                                 || (stream->__modeflags & __FLAG_UNGOT))
                                && fseek(stream, 0L,
...


which is pulled in because of STDIO_STREAM_TRANS_TO_WRITE here:

int VFPRINTF (FILE * __restrict stream,
                          register const FMT_TYPE * __restrict format,
                          va_list arg)
{
...
        if
#ifdef L_vfprintf
        (!__STDIO_STREAM_IS_NARROW_WRITING(stream)
         && __STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_NARROW))
#else
        (!__STDIO_STREAM_IS_WIDE_WRITING(stream)
         && __STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_WIDE))
#endif 

---------------------------------------------------------------------- 
 vda - 04-01-08 12:04  
---------------------------------------------------------------------- 
Seems like it can be improved in _vfprintf.c / old_vfprintf.c
by factoring out "the core" of vprintf() into separate function
(say, "vprintf_internal_unlocked()"), so that:

* vprintf() does locking and __STDIO_STREAM_TRANS_TO_WRITE thing,
  then calls vprintf_internal_unlocked();
* vsnprintf, vdprintf.c, vasprintf.c all use
  vprintf_internal_unlocked() directly
  [and do not need to set up fake locking now] 

---------------------------------------------------------------------- 
 vda - 04-01-08 14:50  
---------------------------------------------------------------------- 
2.patch implements this solution.
3.patch removes unneeded initialization of locking.

If you are going to apply it, take a look at vsnprintf.c's comment about
__bufputc - it seems to be bogus, AFAICS __bufputc initialization has
nothing to do with __user_locking. (I did grep around).

Didn't look yet whether it works with old_vfprintf.c. 

---------------------------------------------------------------------- 
 vda - 04-01-08 15:22  
---------------------------------------------------------------------- 
These patches save http://busybox.net/bugs/view.php?id=115#400 bytes compared to
unpatched uclibc.

Next target can be removing __stdio_fwrite + __stdio_WRITE, as they should
not be needed for sprintf too - projected to save
http://busybox.net/bugs/view.php?id=23#300 bytes. 

---------------------------------------------------------------------- 
 vda - 04-08-08 17:54  
---------------------------------------------------------------------- 
v2 of patches should be more correct wrt old_vsprintf (it is just left
untouched now) 

Issue History 
Date Modified   Username       Field                    Change               
====================================================================== 
04-01-08 09:26  vda            New Issue                                    
04-01-08 09:26  vda            Status                   new => assigned     
04-01-08 09:26  vda            Assigned To               => uClibc          
04-01-08 11:13  vda            Note Added: 0006274                          
04-01-08 12:04  vda            Note Added: 0006284                          
04-01-08 14:46  vda            File Added: 2.patch                          
04-01-08 14:46  vda            File Added: 3.patch                          
04-01-08 14:50  vda            Note Added: 0006294                          
04-01-08 15:22  vda            Note Added: 0006304                          
04-08-08 17:53  vda            File Added: v2_2.patch                       
04-08-08 17:53  vda            File Added: v2_3.patch                       
04-08-08 17:54  vda            Note Added: 0006454                          
======================================================================




More information about the uClibc-cvs mailing list