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++
12600 Discussions

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

Altera_Forum
Honored Contributor II
1,162 Views

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. 

 

 

---------------- 

 

Description: 

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
Reply