Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12622 Discussions

FIY: sprintf function in Nios2 libsmallc.a library returns wrong value

Honored Contributor II

Just submitted the bug report below as Service Request. 

From past experience I expect that the bug will not be fixed in 2012 and, probably, never. So be warned. 






sprintf function supplied with small version of Newlib library for Nios2 (libsmallc.a) returns wrong value. It happens for majority of format specifiers (I checked %c, %d and %u) when they are used without width and/or precision sub-specifiers. 

It is possible that the problem exists not just in sprintf, but in other functions of printf family as well, I didn't test it, because I rarely care for return value of other functions. 


Software versions: all versions of nios2eds suite that come with small library. I am sure that bug exists in versions as early as v.6.1 and as late as 11.1sp2. 


Steps to reproduce: 

1. Create Altera HAL based based bsp with small C library 

2. Create minimalistic "Hello, world" style application with main module like that: 

//----------- main.c# include <stdio.h> 


int main(void) 

char buf[20]; 

int llc = sprintf(buf, "%c", 'x'); 

int lld = sprintf(buf, "%d", 100); 

printf("llc=%d, should be 1. lld=%d, should be 3.\n", llc, lld); 


for (;;); 

return 0; 

//----------- end of main.c 


3. Compile, link and run the application on your favorite Nios2 hardware. See the printout. 

My printout looks like that: 

llc=-1, should be 1. lld=1, should be 3. 



Investigation and suggested solution: 

I traced the bug back to function _vfprintf_r that is implemented in module ./nios2eds/bin/nios2-gnutools/src/newlib/newlib/libc/stdio/vfprintf1.c starting from line 245. 

Specifically, the macro PRINT_REP is wrong. 

Instead of 

------# define PRINT_REP(c, len)  

do {  

if (print_repeat (data, fp, (c), (len)))  

goto error;  

write_count += len;  

} while (0) 


it should be written as: 

----------# define PRINT_REP(c, len)  

do {  

if (len > 0) {  

if (print_repeat (data, fp, (c), (len)))  

goto error;  

write_count += len;  


} while (0) 



It looks like your developer picked code out of old version of BSD library from 22 years ago and didn't pay attention to a fix submitted couple of years later.
0 Kudos
0 Replies