Hard Fault in the "Bfree" function (mprec.c).

Asked by Krzysztof Kawula

Hello. Recently I have been trying to use NewLib-nano(from tool-chain in version 4.8 2014q2) with FreeRTOS(8.0.1).

To get NewLIb nano work with FreeRTOS I did everything according to article:
http://michaldemin.wordpress.com/2010/03/09/freertos-newlib-on-cortex-m3/
so my malloc and free functions looks like these:
https://github.com/robots/STM32/blob/master/lib/FreeRTOS/portable/MemMang/alloc.c
Additional, using flag "configUSE_NEWLIB_REENTRANT" I have configured the FreeRTOS to use separate _reent structure for each thread.

Every things looks to work ok. I have got 3 tasks running on the same priority and they are printing decimal values using printf and semihosting.
Everything is changing when I try to print floating point values. Program prints values correctly but from time to time it gets crash on printf.
After restarting program will crash on exactly the same printf call. But when I Copy it in different place it's executed correctly and correct float values are printed.

As I mention within one executable file the crash point is constant. Function printf call the _dtoa_r and it call Bfree function where program crashed.

I suspect that library is trying to call some allocator which is not correlated with _malloc_r function.

Corrupted print out instruction:
 printf("vSHT1X_TestBench:temp:%5.1fC humi:%5.1f%% dew point:%5.1fC\n",temp_val.f,humi_val.f,dew_point);
Result in the terminal:
 "vSHT1X_TestBench:temp: Ŕ. C humi:"

Debug information:
[Hard fault handler - all numbers in hex]
R0 = 0x200084ec
R1 = 0x00000001
R2 = 0x89080006
R3 = 0x20004c50
R12 = 0x8075b852
LR [R14] = 0x0801fc6f subroutine call return address
PC [R15] = 0x08020a78 program counter
PSR = 0x21000000
BFAR = 0x44204c68
CFSR = 0x00008200
HFSR = 0x40000000
DFSR = 0x00000001
AFSR = 0x00000000
SCB_SHCSR = 00000000

Where fault occurred: -> _Bfree
 .text._Bfree 0x08020a56 0x2e c:/program files (x86)/gnu tools arm embedded/4.8 2014q2/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m\libg_s.a(lib_a-mprec.o)
                0x08020a56 _Bfree
 .text.__multadd
                0x08020a84 0x74 c:/program files (x86)/gnu tools arm embedded/4.8 2014q2/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m\libg_s.a(lib_a-mprec.o)
                0x08020a84 __multadd

Function which call the Bfree: -> _dtoa_r
 .text._dtoa_r 0x0801fc30 0xb80 c:/program files (x86)/gnu tools arm embedded/4.8 2014q2/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m\libg_s.a(lib_a-dtoa.o)
                0x0801fc30 _dtoa_r
 .text.__sflush_r
                0x080207b0 0x106 c:/program files (x86)/gnu tools arm embedded/4.8 2014q2/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m\libg_s.a(lib_a-fflush.o)
                0x080207b0 __sflush_r

Any idea how to fix this issue?
Best Regards, Krzysztof

Question information

Language:
English Edit question
Status:
Answered
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Joey Ye (jinyun-ye) said :
#1

Krzysztof,

Thanks for reporting this issue. However, I could not reproduce your issue
with information you provided. I would check following things:
1. Stack/heap overflow. Float printf need large stack space. If interfering
with heap, it will result in free error
2. Try difference malloc/free to see if they are problemetic

Thanks,
Joey

On Sat, Aug 9, 2014 at 8:43 AM, Krzysztof Kawula <
<email address hidden>> wrote:

> Question #252843 on GCC ARM Embedded changed:
> https://answers.launchpad.net/gcc-arm-embedded/+question/252843
>
> Description changed to:
> Hello. Recently I have been trying to use NewLib-nano(from tool-chain
> in version 4.8 2014q2) with FreeRTOS(8.0.1).
>
> To get NewLIb nano work with FreeRTOS I did everything according to
> article:
> http://michaldemin.wordpress.com/2010/03/09/freertos-newlib-on-cortex-m3/
> so my malloc and free functions looks like these:
>
> https://github.com/robots/STM32/blob/master/lib/FreeRTOS/portable/MemMang/alloc.c
> Additional, using flag "configUSE_NEWLIB_REENTRANT" I have configured the
> FreeRTOS to use separate _reent structure for each thread.
>
> Every things looks to work ok. I have got 3 tasks running on the same
> priority and they are printing decimal values using printf and semihosting.
> Everything is changing when I try to print floating point values. Program
> prints values correctly but from time to time it gets crash on printf.
> After restarting program will crash on exactly the same printf call. But
> when I Copy it in different place it's executed correctly and correct float
> values are printed.
>
> As I mention within one executable file the crash point is constant.
> Function printf call the _dtoa_r and it call Bfree function where
> program crashed.
>
> I suspect that library is trying to call some allocator which is not
> correlated with _malloc_r function.
>
> Corrupted print out instruction:
> printf("vSHT1X_TestBench:temp:%5.1fC humi:%5.1f%% dew
> point:%5.1fC\n",temp_val.f,humi_val.f,dew_point);
> Result in the terminal:
> "vSHT1X_TestBench:temp: Ŕ . C humi:"
>
> Debug information:
> [Hard fault handler - all numbers in hex]
> R0 = 0x200084ec
> R1 = 0x00000001
> R2 = 0x89080006
> R3 = 0x20004c50
> R12 = 0x8075b852
> LR [R14] = 0x0801fc6f subroutine call return address
> PC [R15] = 0x08020a78 program counter
> PSR = 0x21000000
> BFAR = 0x44204c68
> CFSR = 0x00008200
> HFSR = 0x40000000
> DFSR = 0x00000001
> AFSR = 0x00000000
> SCB_SHCSR = 00000000
>
>
>
> Where fault occurred: -> _Bfree
> .text._Bfree 0x08020a56 0x2e c:/program files (x86)/gnu tools arm
> embedded/4.8
> 2014q2/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m\libg_s.a(lib_a-mprec.o)
> 0x08020a56 _Bfree
> .text.__multadd
> 0x08020a84 0x74 c:/program files (x86)/gnu tools arm
> embedded/4.8
> 2014q2/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m\libg_s.a(lib_a-mprec.o)
> 0x08020a84 __multadd
>
> Function which call the Bfree: -> _dtoa_r
> .text._dtoa_r 0x0801fc30 0xb80 c:/program files (x86)/gnu tools arm
> embedded/4.8
> 2014q2/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m\libg_s.a(lib_a-dtoa.o)
> 0x0801fc30 _dtoa_r
> .text.__sflush_r
> 0x080207b0 0x106 c:/program files (x86)/gnu tools arm
> embedded/4.8
> 2014q2/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m\libg_s.a(lib_a-fflush.o)
> 0x080207b0 __sflush_r
>
>
> Any idea how to fix this issue?
> Best Regards, Krzysztof
>
> --
> You received this question notification because you are an answer
> contact for GCC ARM Embedded.
>

Revision history for this message
Charles Lohr (charles-cnlohr) said :
#2

I am running into a suspiciously similar error, though I am only using newlib, no OS. My crash happens in __sflush_r / _free_r, and may or may not crash depending on the alignment of the code. If I add/remove nop's in certain places, it can cause the crash to come or go. It seems that my stack / heap is okay.

FLASH 0x0000000008000000 0x0000000000100000 xr
RAM 0x0000000020000000 0x0000000000020000 xrw
RAM_CCM 0x0000000010000000 0x0000000000010000 xrw
MEMORY_B1 0x0000000060000000 0x0000000000000000 xr
*default* 0x0000000000000000 0xffffffffffffffff

                0x0000000020020000 _estack = 0x20020000
                0x0000000000001000 _Min_Heap_Size = 0x1000
                0x0000000000000600 _Min_Stack_Size = 0x600

I've got a ton of free space:
._user_heap_stack
                0x0000000020012eb8 0x1600 load address 0x00000000080291f0
                0x0000000020012eb8 . = ALIGN (0x4)
                0x0000000020012eb8 PROVIDE (end, .)
                0x0000000020012eb8 PROVIDE (_end, .)
                0x0000000020013eb8 . = (. + _Min_Heap_Size)
 *fill* 0x0000000020012eb8 0x1000
                0x00000000200144b8 . = (. + _Min_Stack_Size)
 *fill* 0x0000000020013eb8 0x600
                0x00000000200144b8 . = ALIGN (0x4)

I have checked the output of my _sbrk function, and it initially returns 0x20012eb8, then it returns 0x200132d0, after a incr of 0x418 then 0xd30 was requested, so it appears that is working correctly.

How do I override free/malloc?

Any other ideas?

Revision history for this message
Charles Lohr (charles-cnlohr) said :
#3

I just found my problem: It was that it was passing a bad pointer to setvbuf, which didn't cause a problem most of the time, but every now and then ended badly. Sadly, this means that my problem is likely different than the original one, despite the __sflush_r matching.

Can you help with this problem?

Provide an answer of your own, or ask Krzysztof Kawula for more information if necessary.

To post a message you must log in.