Threads using sprintf with float

Bug #1510330 reported by Nick
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
GNU Arm Embedded Toolchain
New
Undecided
Unassigned

Bug Description

OS: CMSIS RTX
GCC ARM: 4.9 2015q3
Libs: nosys
Linker: --specs=nano.specs -u _printf_float

Hi,

I have faced and issue when using sprintf with floats. I have 2 threads using sprintf a number and after a while it will hardfault.
Sbrk will return if there is no heap left and malloc is guarded with a mutex. It seems to free a non valid address and then corrution begins. It apparently fails only with floats.

This is how you can replicate it.

void function_to_call(char *str, float *number, char *value) {
  sprintf(value,"%.5f\n",*number);
  sprintf(str,"%s%u%s %s\n","Gen",1,"Load",value);
}

void test_var_string_1(void const *arg) {

  char str[128];
  char value[32];
  float number = 0;

  printf(" \n thread 1 \n");

  while(1) {

    for (uint32_t i = 0; i < 200; i++){
      function_to_call(str, &number, value);
      number++;
    }

    osDelay(10);

  }

}

void test_var_string_2(void const *arg) {

  char str[128];
  char value[32];
  float number = 0;

  printf(" \n thread 2 \n");

  while(1) {

    for (uint32_t i = 0; i < 200; i++){
      function_to_call(str, &number, value);
      number++;
    }

    osDelay(10);

  }

}

osThreadDef (test_var_string_1, osPriorityLow, 1, 0);
osThreadDef (test_var_string_2, osPriorityLow, 1, 0);

void main(void){

   osThreadCreate (osThread(test_var_string_1), NULL);
   osThreadCreate (osThread(test_var_string_2), NULL);

  for(;;){

     osDelay(100);

  }

}

Revision history for this message
Joey Ye (jinyun-ye) wrote :

newlib-nano is not thread safe. It is recommended to use newlib instead in your case.

Revision history for this message
Nick (n-karakotas) wrote :

Hi,

I removed nospec.nano and nosys. It still produces the same result.

Nick

Revision history for this message
Joey Ye (jinyun-ye) wrote :

Then can you please check stack size. printing floating point consume lot of stack space, which may result in overflow.

Revision history for this message
Nick (n-karakotas) wrote :

I changed OS_STACK_SIZE to 3000 and it still crashes

Revision history for this message
Nick (n-karakotas) wrote :

Hardfault info
PC 803c5ac

0803c58a <_Bfree>:
 803c58a: b570 push {r4, r5, r6, lr}
 803c58c: 6a44 ldr r4, [r0, #36] ; 0x24
 803c58e: 4606 mov r6, r0
 803c590: 460d mov r5, r1
 803c592: b93c cbnz r4, 803c5a4 <_Bfree+0x1a>
 803c594: 2010 movs r0, #16
 803c596: f7d8 fcd9 bl 8014f4c <__wrap_malloc>
 803c59a: 6270 str r0, [r6, #36] ; 0x24
 803c59c: 6044 str r4, [r0, #4]
 803c59e: 6084 str r4, [r0, #8]
 803c5a0: 6004 str r4, [r0, #0]
 803c5a2: 60c4 str r4, [r0, #12]
 803c5a4: b13d cbz r5, 803c5b6 <_Bfree+0x2c>
 803c5a6: 6a73 ldr r3, [r6, #36] ; 0x24
 803c5a8: 686a ldr r2, [r5, #4]
 803c5aa: 68db ldr r3, [r3, #12]
 803c5ac: f853 1022 ldr.w r1, [r3, r2, lsl #2]
 803c5b0: 6029 str r1, [r5, #0]
 803c5b2: f843 5022 str.w r5, [r3, r2, lsl #2]
 803c5b6: bd70 pop {r4, r5, r6, pc}

Revision history for this message
Nick (n-karakotas) wrote :

Hard fault info

R0 = 0x200001ec
R1 = 0x3030
R2 = 0xf8be8b84
R3 = 0x2001b480
R12 = 0x81b8e080
LR [R14] = 0x803ac23 subroutine call return address
PC [R15] = 0x803c5ac program counter
PSR = 0x21000000
BFAR = 0x2fbe290
CFSR = 0x8200
UFSR = 0x0
HFSR = 0x40000000
DFSR = 0x0
AFSR = 0x0
MMAR = 0x2fbe290

Revision history for this message
Joey Ye (jinyun-ye) wrote :

Took a quick look at the code dump but had no clue what was wrong. Plus the information provided here is not sufficient to reproduce it in my side. So far I haven't noticed any evidence that compiler/library is doing wrong.

Revision history for this message
Dave Nadler (drn-nadler) wrote :

@Nick (n-karakotas) - This not a toolchain bug at this level. Please see the heap_useNewlib section in the following for explanation and code to fix your problem: https://github.com/DRNadler/FreeRTOS_helpers
Hope that helps someone!
Best Regards, Dave

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.