Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

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

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.
No RepliesBe the first to reply