cancel
Showing results for 
Search instead for 
Did you mean: 

memcpy problem

pcu
Associate II
Posted on October 08, 2013 at 13:49

Hello,

I work with a STm32F417 FreeRTOS + lwip 1.4.0 + 7.1.1.

I get crash HardFault_Handler. Sometimes after a few minutes, sometimes after a few hours.

There is a screenshot in attachment.

I can see that it comes from memcpy (). If I am correct about assembler it is: load into r4 the value contained at r1+r3: (0x20001FF7C + 0x84).

That is to say, in the heap memory if I look into .map? Strange because I do not use traditional malloc ()?

My analysis may be wrong?

Thank you for your help.

Pierre

8 REPLIES 8
Posted on October 08, 2013 at 15:27

More probably the stack, and blowing through the top of RAM.

If you know the specific memcpy(), you could place sanity checks around it to assure you don't exceed the scope of the buffer/whatever that is being used.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dthedens23
Associate II
Posted on October 08, 2013 at 16:06

If you are using FreeRTOS then you are using some sort of heap (look at the config file).

(one of the things I dislike about FreeRTOS, some of us cannot use malloc, every object must be compile time allocated)

None of the standard library functions (like memcpy, printf, malloc,...) should be considered thread safe.

that means, if two threads use stdlib functions and a context switch occurs while one thread is inside one of these functions, and the other thread calls the stdlib, then the results are undetermined.  Some stdlib functions are well behaved, some are not.

you should update to FreeRTOS v7.5.  many fixes improvements from v7.1

dthedens23
Associate II
Posted on October 09, 2013 at 16:46

oh yea, see if there is an option to use character based printf rather than string based.  It is a blocking call, but it is safer for RTOS.

By default

printf()

and

puts()

make use of

malloc()

to provide a temporary buffer on

the heap in order to generate the string to be displayed. 

carl2399
Associate II
Posted on October 11, 2013 at 01:25

I had a related problem which I'll share as you may be experiencing the same.

I use the GCC compiler which I use to compile both C and C++ applications for STM32. When using memcpy() the compiler includes optimisations to use the stmdb and ldmia instruction to copy multiple items at a time. While the normal ldr and str instructions are able to work just fine with non-aligned memory pointers, the ldmia and stmdb instructions resulted in hard faults (although maybe memory faults).

If you use Google you can find other references to this issue, and also how to specify the variables to stop this optimisation from happening - or at least only be applied when the memory being copied is correctly aligned. I can't remember the exact details though, as I wrote my own memcpy replacement instead.  

pcu
Associate II
Posted on October 12, 2013 at 15:40

Thank you for your different replies.

I tried to use my own memcpy. The problem is the same.

BUT now I can add a breakpoint in the memcpy if the souce or destination pointer is above a boundary and I can analyse the call hierarchy before it crash.

I have an idea for the origin of the problem but I have to let it run to confirm this.

pcu
Associate II
Posted on October 14, 2013 at 17:16

Now I'm sure this is not memcpy. It is a stack overflow. In fact I think I had a problem with lwip and one with memcpy but in reality it is the same. The program accesses at 0x20020000 address.

It could be after 5 minutes of after a couple of hours.

I upgraded to FRTOS 7.5.2 and in same time improves the interrupt configuration with help of assert.

I enabled MEMP_SANITY_CHECK and MEMP_OVERFLOW_CHECK in lwip. I don't get error message on terminal, only the program crashes early in memp_sanity () (before it was in memcpy).

It seems GCC creates local variables at the end of the memory.

I don't know how to find the leakage of memory? I added a data breakpoint near the end of RAM but not easy to interpret if it is correct access or not.

Does a 

trace-

debugger might help?

 

Posted on October 14, 2013 at 17:43

The local variable are at the top of memory due to the placement of the stack there.

You could move it lower and put a guard zone there, but that wouldn't stop the code reading where it shouldn't be.

Not sure making it bigger helps either, but rather that you have an array, buffer, whatever that you are exceeding. Say the buffer has space for 32 bytes, and you're trying to move 160 or something.

Your job is to understand what's going on with the data manipulation or buffer management to cause this problem.

Would trace help, perhaps, it might tell you how you arrived at a specific point, but at this point you should know which instantiation of memcpy() is failing, and how to catch that condition before it faults the processor. You could just as easily instrument the code to output diagnostic information about how it arrived there too. The goal is to recognize the failure condition, and work backward up the call tree, and passed data structures.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
emalund
Associate III
Posted on October 14, 2013 at 22:20

not working with ST at this time I can only say what I did last with another brand.

find the hard fault handler, insert a while (1); and when the blow occor, set a breakpoint on the while.  There is a lot of good info to be had.

an even sneakier way is

char blah =1;

while (blah)

return

then on the hang break on blah change to 0 and step to where the hard fault happened