BusyBox Bug and Patch Tracking
BusyBox
  

Viewing Issue Simple Details Jump to Notes ] View Advanced ] Issue History ] Print ]
ID Category Severity Reproducibility Date Submitted Last Update
0002714 [uClibc] Stdio minor always 04-01-08 09:26 04-09-08 12:52
Reporter vda View Status public  
Assigned To uClibc
Priority normal Resolution fixed  
Status closed   Product Version 0.9.28.1
Summary 0002714: 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.
Additional Information function old new delta
_string_syserrmsgs - 2906 +2906
_fpmaxtostr - 1479 +1479
vfprintf - 1159 +1159
__GI_vfprintf - 1159 +1159
_ppfs_parsespec - 840 +840
__GI___C_ctype_b_data - 768 +768
__C_ctype_b_data - 768 +768
_ppfs_setargs - 277 +277
_uintmaxtostr - 228 +228
__stdio_fwrite - 213 +213
memrchr - 177 +177
__GI_memrchr - 177 +177
__xpg_strerror_r - 170 +170
__GI___xpg_strerror_r - 170 +170
fseeko64 - 131 +131
__GI_fseeko64 - 131 +131
vsnprintf - 127 +127
__GI_vsnprintf - 127 +127
__stdio_trans2w - 126 +126
__stdio_WRITE - 117 +117
__stdio_adjust_position - 106 +106
_ppfs_init - 102 +102
fwrite_unlocked - 93 +93
fwrite - 93 +93
__GI_fwrite_unlocked - 93 +93
__GI_fwrite - 93 +93
__libc_lseek64 - 88 +88
_load_inttype - 86 +86
_store_inttype - 61 +61
_ppfs_prepargs - 57 +57
__stdio_seek - 46 +46
fputs_unlocked - 45 +45
fputs - 45 +45
__GI_fputs_unlocked - 45 +45
__GI_fputs - 45 +45
__stdio_wcommit - 37 +37
memchr - 35 +35
__GI_memchr - 35 +35
sprintf - 30 +30
__GI_sprintf - 30 +30
__glibc_strerror_r - 26 +26
__GI___glibc_strerror_r - 26 +26
strnlen - 25 +25
__GI_strnlen - 25 +25
fseeko - 24 +24
fseek - 24 +24
__GI_fseek - 24 +24
__ctype_b - 4 +4
__GI___ctype_b - 4 +4
------------------------------------------------------------------------------
(add/remove: 49/0 grow/shrink: 1/0 up/down: 12711/0) Total: 12711 bytes

Archive member included because of file (symbol)

/usr/lib/../i486-linux-uclibc/lib/libc.a(vfprintf.o)
<= /usr/lib/../i486-linux-uclibc/lib/libc.a(vsnprintf.o) (__GI_vfprintf)
Attached Files  2.patch [^] (16,000 bytes) 04-01-08 14:46
 3.patch [^] (2,660 bytes) 04-01-08 14:46
 v2_2.patch [^] (15,747 bytes) 04-08-08 17:53
 v2_3.patch [^] (2,220 bytes) 04-08-08 17:53

- Relationships

- Notes
(0006274)
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
 
(0006284)
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]
 
(0006294)
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.
 
(0006304)
vda
04-01-08 15:22

These patches save Note: 0000400 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 Note: 0000300 bytes.
 
(0006454)
vda
04-08-08 17:54

v2 of patches should be more correct wrt old_vsprintf (it is just left untouched now)
 
(0006494)
vda
04-09-08 12:52

Applied as revisions 21683 and 21684.
 

- 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
04-09-08 12:52 vda Status assigned => closed
04-09-08 12:52 vda Note Added: 0006494
04-09-08 12:52 vda Resolution open => fixed


Copyright © 2000 - 2006 Mantis Group
Powered by Mantis Bugtracker