Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training


sprintf %f corrupts stack

Posted by dnadler on December 26, 2016

I'm not sure this is a FreeRTOS problem, but... Cortex M4F (Kenetis K64), gcc, nano, newlib with float. Only one task uses floating point; no issues there. A sprintf of a floating point number returns the correct string but corrupts the stack. The corruption is miles away from the top of the stack. FreeRTOS-aware debug says I have several kb of extra stack space for this task. Absolutely reproducible; this corrupts stack: sprintf(out.pBuffer,"floatOutTest=%f", 1.2345f); The buffer is in the right place and printing decimal values works fine. Thanks in advance for any ideas! Best Regards, Dave

sprintf %f corrupts stack

Posted by rtel on December 27, 2016

Things to check:

1) The stack is 8 byte aligned at the point sprintf() is called (put a breakpoint on the call to sprintf() and check the value of the stack pointer in the debugger).

2) Are you using a FreeRTOS heap memory allocator other than heap3.c? If so, check sprintf() is not calling malloc(). heap3.c is the only FreeRTOS memory allocator that will need malloc() to be configured correctly, and if it is not configured and sprintf() attempts to call it then anything could happen. Probably the easiest way to check this is to provide your own implementation of malloc() that does nothing but contain an NOP instruction, or trigger an assert, then put a break point in your implementation of malloc() and see if it is ever called.

sprintf %f corrupts stack

Posted by dnadler on December 27, 2016

Stack alignment is AOK. I'm using your heap4. Per your suggestion I added a dummy malloc with asm bkpt, and sure enough the damn thing is calling malloc: ** sprintf -> _svprintfr -> printffloat -> cvt -> dtoar -> malloc ** Unfortunately I don't have a library built with debug info. I suspect malloc is incorrectly set up by NXP/Freescale (dubious linker script with partioned M4F RAM) and/or its run out of the standard RTL heap's memory. I could try stubbing it out with heap_4... Thanks for the help! Best Regards, Dave

sprintf %f corrupts stack

Posted by dnadler on December 28, 2016

Update: Several nano newlib RTL functions (sprintf, strtok) unexpectedly used malloc() or mallocr().

The default heap from Freescale/NXP was set to 1kB (for a processor with 256kB RAM!), and the RTL overflowed the heap without halting and corrupted memory. Very Nice!

Do you guys have a replacement for the nano free storage functions that map to FreeRTOS heap functions, to give a single, debuggable pool? Ideally with hard stop on overrun? Is this a bad idea? Should I write this?

Thanks as always, Best Regards, Dave

sprintf %f corrupts stack

Posted by rtel on December 28, 2016

You can provide your own doing something simple such as:

void *malloc( size_t xBytes )
     return pvPortMalloc( xBytes );

void free( void *pvBuffer )
     vPortFree( pvBuffer );

The configASSERT() calls in pvPortMalloc() and vPortFree() will then work as normal. If you are using GCC (and maybe other compilers) then there is a way of redirecting these calls using the command line - but its probably easier and more portable just to add the above functions into your code.

sprintf %f corrupts stack

Posted by dnadler on December 28, 2016

If I understand correctly, its a bit more complicated, as there is a whole family of heap routines included in newlib, and used within newlib. One example above is mallocr(). See newlib's malloc.c source for the entire set. No?

sprintf %f corrupts stack

Posted by richard_damon on December 28, 2016

One issue I have seen with some Librararies is they assume the heap can grow up to the stack, and once the kernal is started, the memory map is no longer what they expect. Sometimes using the heap prior to starting the kernal can help. I would make everything use the same heap either like posted above or making FreeRTOS use the libary heap (adding the needed code to make the library heap thread safe).

sprintf %f corrupts stack

Posted by ammaree on January 5, 2017

Maybe a suggestion to have a look at a complete [v/s/n/f]printf replacement on github. I uses no dynamic memory, supports floats and have a large number of optional extension that can be useful in an embedded environment.

The supported functions can be selected at compile time to minimise the stack space used. Stack usage is completely predictable with no recursion.

The printf functionality relies ()to some extent) on 2 additional modules also there namely xtime.c and xstring_general.c, so scratch around...

Have a look at https://github.com/ksstech/support_common and shout if you have queries or suggestions, but it is fairly well documented in the source code.

sprintf %f corrupts stack

Posted by dnadler on February 26, 2017

Thanks Andre for the suggestion.

Richard, can you point me at a replacement for newlib's malloc and friends, that properly uses FreeRTOS heap functions and reentrancy structures?

Thanks, Best Regards, Dave

sprintf %f corrupts stack

Posted by richarddamon on February 27, 2017

I just downloaded the newlib-nano repository itself and added the defines used to enable the reentrancy callls. These then call functions _malloclock and _mallocunlock which can just call the scheduler suspend/resume functions like in heap_3.c

I will need to get the exact repository address and files from work tomorrow. The queston comes to what options were the library compiled with, if it was compiled with full re-entrancy endabled, you may just need to define the malloc_lock/malloc_unlock functions.

sprintf %f corrupts stack

Posted by hs2sf on February 27, 2017

Alternatively you could make use of the 'wrap symbol' linker feature e.g. let the linker replace all 'malloc' symbols with (your) __wrap_malloc implementation etc. You might even implement your own low level _sbrk function. (I've also overloaded the global new/delete operators with 'noexcept' versions to safe some code space.) Good luck, HS2

sprintf %f corrupts stack

Posted by richarddamon on March 2, 2017

The newlib repository is at sourceware.org

In my case, the enviroment was already using newlib-nano, the package just wasn't quite configured the way I needed. The use of newlib-nano seems fairly common if you have a gcc based development tool.

If so, first I would see if it is configured to use the interlock functions already. See if a _malloclock() / _mallocunlock functions stubs are already being used. If they are, you just need to define the lock function to call vTaskSuspendAll() and the unlock to call vTaskResumeAll() (and then test that these are called by malloc) and you are set.

If not, you can just add the source code for the malloc module (newlib/libc/stdlib/nano-mallocr.c) to your project. There are other files malloc.c and mallocr.c too that you don' need (malloc.c is a stub to allow newlib to have reentrant routines, including malloc, and mallocr.c is a 'big machine' version of the reentrant malloc).

If your library isn't based on newlib, you could still look at the newlib version to build a malloc for your self, but check if your library malloc does the work or if it just forwards to some other function.

[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]

Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.

Free TCP/IP and file system demos for the RTOS

Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑

FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists