| Anonymous | Login | Signup for a new account | 11-10-2008 11:53 PST |
| Main | My View | View Issues | Change Log | Docs |
| 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 |
|
||||||||
|
|
|||||||||
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. |
| Copyright © 2000 - 2006 Mantis Group |