This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

printf bug?

Other Parts Discussed in Thread: MSP430F5438

Hello, 

I have a question about the stdlib printf functions. If I use not "valid" floating point numbers, which is the case when memory is not initialized, then my snprintf function "hangs" (is looping internally). I have increased the heap to 500 and stack to 200. I am using CCS 5.1.1.00028 and MSP430.  I tried compiler toos 4.0.0, 4.0.2, and 4.1.0 but nothing worked. 

Do I have to provide some error callback functions? Where can I find detailed documentation about how to implement this functions?

Is this a bug?

If this is not a bug, how can I check if it is a valid floating point value?

Reproducible code:

void main(void) 
{
	char str[40];
	volatile float test;

	((char*)&test)[0] = 0x6d;
	((char*)&test)[1] = 0x6d;
	((char*)&test)[2] = 0;
	((char*)&test)[3] = 0;


	 while(1)
	 {
		 snprintf(str, 30, "%f", test);
		 _NOP();
	 }
}

Thanks,

Joachim

  • For IEEE-754 32-bit format, 0x00006d6d is 3.92546e-41f, which  is a denormal (subnormal) number.  The TI compiler doesn't support denormal numbers, and that in part manifests as library functions which can't handle them as input, and which do bad things like loop forever or return bogus results.  You have to take care not to pass such numbers to any library function.  There isn't a library function which tests whether a given bit pattern represents an IEEE-754 value that the library can handle.

    In addition, it's technically undefined behavior to pass an uninitialized value to a library function, so doing so is not portable.

  • Hello Archaeologist,

    ok - so does that mean if I want to create a robust software, I have to validate every floating point value that is loaded from external memory or internal flash? In my case I am storing floating point values in flash memory. Anyway, how do I check this correctly? 

    Suppose the memory from where the application is "loading" the float values gets corrupted (power loss or something else) and these values are not validated then the application crashes. There helps no watchdog or other mechanism because every thime the application crashes... Strange behavior in my opinion. Other implementations of printf I have seen prints a "NAN" or simply "0" but such behavior I havent seen until now.

    Does TI somewhere  inform customers about this behavior?

    Thanks for helping,

    Joachim

  • Unfortunately, there is no solution at the moment.  The TI library doesn't make any sort of allowance for potentially corrupted floating-point input.  The issue runs deeper than just printf; the underlying floating-point emulation functions need to be overhauled to support Inf, NaN, and denormals correctly.  Certainly, we would prefer that printf at least not crash in the face of corrupted input, but fixing the floating-point emulation on a device that doesn't have floating-point hardware just doesn't get prioritized over the other work that needs to be done.  I've submitted SDSCM00043971 to track this issue.

    I can think of only one workaround: don't print float values that aren't known to be correct.  Values can be assumed to be correct if they are generated by the program, or you could write a function to pick the bits apart and test for special values like NaN, Inf, -0, and denormal numbers.  I know this is unpleasant, but that's the way it is today.

    No, there is no documentation on the flaws of floating-point in TI compilers that I'm aware of.

  • Hello,

    first thank you for your help. I am developing now embedded software for now about 12 years, worked with a lot of compilers until now. For me this is clearly a bug and maybe a big security risk for some applications, too. I will try to find an secure workaround.

    > Certainly, we would prefer that printf at least not crash in the face of corrupted input, but fixing the floating-point emulation on a device that doesn't have floating-point hardware just doesn't get prioritized over the other work that needs to be done.

    Hm - I thought that CCS is TI´s pfefered compiler for MSP430? No MSP430 device has an fpu as far as I know.  Does TI really think that no one uses floating point operations in your devices without fpu? I hope not ;)

    Sorry Archaeologist for this discussion - I just want to make clear that TI has to solve this issue and not only years later. Perhaps TI sees this with other eyes but I would not buy security devices if would know the controller has such "feature" ;)

    TI should mention this somewhere that there exists this known problem. 

    Again thanks for helping,

    Joachim

  • Archaeologist said:
    No, there is no documentation on the flaws of floating-point in TI compilers that I'm aware of.

    In the absence of documentation it is possible to run a floating-point test program. e.g. running Embedded System Paranoia: a tool for testing embedded system arithmetic on a MSP430F5438 when compiled for debug using MSP430 Compiler V4.1.0 produced the attached results. Note the overall rating for this test program of  "Unacceptable".

  • Results of single precision attached.

  • Hello Chester,

    very interesting, thanks.

    Regards,

    Joachim

  • 8883.double_results.txt
    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    COMMENT: =========================================
    COMMENT: Welcome to ESP - Embedded System Paranoia
    COMMENT: Please let me know your experiences
    COMMENT: and suggestions at lesh@oakcomp.co.uk or
    COMMENT: L.Hatton@kent.ac.uk
    COMMENT:
    COMMENT: $Revision: 1.9 $ $Date: 2004/04/13 14:21:53 $
    COMMENT: This version will attempt divide by zero.
    COMMENT: This version uses <stdio.h>
    COMMENT: This version uses <setjmp.h>
    COMMENT: This version uses double precision. nbits=64
    COMMENT: =========================================
    -------> Diagnosis resuming after Milestone 0, Page 1
    COMMENT: -1, 0, 1/2, 1, 2, 3, 4, 5, 9, 27, 32 & 240
    PASSED : small integer tests are all OK.
    COMMENT: Searching for Radix and Precision.
    COMMENT: Radix = 2.00000000000000000e+00
    COMMENT: Closest relative separation found is U1 = 1.11022302462515654e-16
    COMMENT: Recalculating radix and precision
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    8156.single_results.txt
    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    COMMENT: =========================================
    COMMENT: Welcome to ESP - Embedded System Paranoia
    COMMENT: Please let me know your experiences
    COMMENT: and suggestions at lesh@oakcomp.co.uk or
    COMMENT: L.Hatton@kent.ac.uk
    COMMENT:
    COMMENT: $Revision: 1.9 $ $Date: 2004/04/13 14:21:53 $
    COMMENT: This version will attempt divide by zero.
    COMMENT: This version uses <stdio.h>
    COMMENT: This version uses <setjmp.h>
    COMMENT: This version uses single precision, nbits=32
    COMMENT: =========================================
    -------> Diagnosis resuming after Milestone 0, Page 1
    COMMENT: -1, 0, 1/2, 1, 2, 3, 4, 5, 9, 27, 32 & 240
    PASSED : small integer tests are all OK.
    COMMENT: Searching for Radix and Precision.
    COMMENT: Radix = 2.0000000e+00
    COMMENT: Closest relative separation found is U1 = 5.9604645e-08
    COMMENT: Recalculating radix and precision
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Chester Gillon said:
    Note the overall rating for this test program of  "Unacceptable".

    The test runs which reporting an overall rating of "Unacceptable" were compiled with the pre-defined symbol NOSETJMP.

    It turns out that there is a bug in esparanoia.c when NOSETJMP was defined which overwrote some variables. With NOSETJMP removed from the project, the overall rating for single and double precision was "Good". The updated results are attached.

    I will contact the auther of Embedded System Paranoia.

  • Dear TI Support,

    I know this post is a bit old, but I need to make a comment on this as it might potencially affect the firmware security in an applicaction with the DSP320F28335 (C28x).

    This  DSP has a FPU (floating point unit) so it has the floating point hardware, no need for software emulation. Also I have routines to inspect parameters in flash which could be viewed as integer, float, etc, being printed to a terminal.

    For any reason, through a floating point operation, the parameter value gets NAN or Infinity (I believe the C28x treats both as Infinity). The sprint function makes the DSP to hang or it is in a loop (I could not check the actual state).

    So here is a case that the NAN value is generated by code. Of course we should not pass a NAN to sprintf.

    So I would much appreciate to know if is there a way to detect and prevent it from occurring, beyond if(x>FLOAT_MAX). If there existed any fucntion like isnan() or isinf() already supported by TI, I would like to hear about it.

    Thanks.

  • Hi,

    Check your math.h header, there you must find isnan and isinf macros.

    BR

  • Hi,

    I have Compiler C2000 v6.1.3. The "math.h" in this version has no isnan() isinf() functions or macros. I have searched and surprisingly they are present in all the compilers except in C2000.

    I also use function "atof" to make inverse conversion and I presume it has similar problem. I would like to make it bullet proof against any bad input from terminal. I have tried to input 1e305 and it just rebooted inmediately. It does not even set to NAN. I suspect "atof"could have a similar problem and I wonder if is there a fix or workaround, to avoid calling this function.

    Thank you in advance

    BR

  • Julio P��rez Arranz said:
    I have Compiler C2000 v6.1.3. The "math.h" in this version has no isnan() isinf() functions or macros.

    The 6.2.x series of releases supports the isnan and isinf macros. The latest version available now is 6.2.7.  Is it practical for you to upgrade your compiler?

    Thanks and regards,

    -George