cancel
Showing results for 
Search instead for 
Did you mean: 

why _malloc_r() running from printf() access invalid address (0x800000) and causes BusFault

SChun.7
Associate II

Hi,

I am testing ThresholdDetection example of FlightSense on Nucleo_STM32F401RE, the code works fine with default setting as 4x4 resolution in MX_53L5A1_ThresholdDetection_Process(). Changing resolution to 8x8, printf() goes into HardFault_Handler(), from debug console the instruction prior to exception handler is _malloc_r() accessing 0x800000 address. Increasing both heap and stack size to 0x8000 does not help.

However, adding printf() in main.c (i.e. prior to running MX_53L5A1_ThresholdDetection_Process()), the code works fine without exception.

My questions: (1) why printf() accessed invalid memory address after changing 4x4 to 8x8? (2) why adding printf() in main.c resolved it without exception? (3) how to identify the root cause?

Any help and suggestion is pretty appreciated.

Thanks~

3 REPLIES 3
SChun.7
Associate II

Hi Pavel,

Thanks for response.

Referred to https://community.st.com/s/question/0D50X0000CBmXufSQF/newlibmalloc-locking-mechanism-to-be-threadsafe I replace sysmem.c to be thread-safe. Setting breakpoint at _critical_section_enter() I confirm the code calls into _malloc_lock(), however the program runs to HardFault_Handler() right after returning from _malloc_lock(). Stepping to next instructions (at 0x0800C342) after _malloc_lock(), it tries to access memory 0x800000 pointed by r6 (or 0x20002250).

disassembly of _malloc_r below

     _malloc_r:

0800c315:  stmdb  sp!, {r4, r5, r6, r7, r8, lr}

0800c319:  adds  r5, r1, #3

0800c31b:  bic.w  r5, r5, #3

0800c31f:  adds  r5, #8

0800c321:  cmp   r5, #12

0800c323:  it   cc

0800c325:  movcc  r5, #12

0800c327:  cmp   r5, #0

0800c329:  mov   r7, r0

0800c32b:  blt.n  0x800c330 <_malloc_r+28>

0800c32d:  cmp   r1, r5

0800c32f:  bls.n  0x800c33c <_malloc_r+40>

0800c331:  movs  r3, #12

0800c333:  str   r3, [r7, #0]

0800c335:  movs  r6, #0

0800c337:  mov   r0, r6

0800c339:  ldmia.w sp!, {r4, r5, r6, r7, r8, pc}

0800c33d:  ldr   r6, [pc, #184] ; (0x800c3f8 <_malloc_r+228>)

0800c33f:  bl   0x8001ea8 <__malloc_lock>

0800c343:  ldr   r3, [r6, #0]

0800c345:  mov   r4, r3

0800c347:  cbnz  r4, 0x800c396 <_malloc_r+130>

0800c349:  mov   r1, r5

0800c34b:  mov   r0, r7

0800c34d:  bl   0x800c2d4 <sbrk_aligned>

......

If I change sensor resolution from 8x8 to 4x4, the memory pointed by r6 of the same instruction is 0x0 at this time, the code runs without any problem.

Any clue or suggestion to figure out the root cause is much appreciated!

Thanks,

Sean

SChun.7
Associate II

I found the root cause is illegal access to memory out of the declared thresholds[64] array. Everything is just fine for 4x4 resolution, however the code tries to access thresholds[64] in case of 8x8 zone resolution, which is conflicted to a pointer (e.g. 0x20002250) used in _malloc_r(). The content is rewritten to 0x800000 and therefore accessing to such memory address results into an exception.