01-06-2017 07:03 AM
I have finally found source of annoying strange behaviour in my aplication for Microblaze.
Short story: I had arrays of hundreds structs what I initialiazed to defined parameters. Then I printed every member one by one with printf() and checked for errors. I found just ONE member what was initialized incorrectly. I was trying to track source of problem in my code and I basically ended in funny state.
Something like this...
struct myStruct myStruct_array; //...some code with initialization, myStruct_array.element should be 0 printf("%d\n", myStruct_array.element); // 0 printf("%d\n", myStruct_array.element); // random
Do you expect I got printed two same numbers? No...First print was correct, the second was something random number (another prints were same).
First I was suspecting errors in my own code with memory corruption - but this was stupid, because there was no code between "separate" calls of printf(). There were no interrupts etc
So I tried disassembly these lines of code with debugger and I found that printf uses malloc what was possibly source of problems.
Another problem was with assert macros from xil_assert.h. Assertion fails caused reset of program instead of printing number of line and file with problem and blocking the code with infinitive loop.
I have replaced printf by xil_printf and everything works fine for now but I wanted to use the standart printf() because of no limitations (xil_printf can't print 64bit numbers, float etc). I have DDR memory so I don't have to bother about saving memory space etc.
Why there is no warning about this in documentation? (for example OS and Libraries Document Collection)
I have just foung mention here: https://www.xilinx.com/support/answers/23345.html
01-06-2017 09:21 AM
Regarding to the issues with printf function, as long as it makes use of dynamic memory allocation and calls to malloc, you should check your HEAP size, as pointed in the UG645 (Memory Management Functions).
On the other hand, xil_assert does not print any line in your serial terminal by default. You have to register your own assert callback to define the exact behavior of your system, using Xil_AssertSetCallback() function, where the callback has as input the file name and the specific line where the assert has been trapped. Your callback then can decide to print a message or stop in an infinite loop.There is also a variable called Xil_AssertWait that you can set to 1 if you want include the infinite loop behavior in the default callback. Detailed info of each function can be found the in the same UG645.
01-06-2017 02:01 PM
I had registered callback for xil_assert and it worked fine before I used printf function. I just wanted to point that using print() function corrupted the program code somehow and it was hard to find.
Is possible to detect overflow of HEAP? I know there is something fot stack in GCC (Stack-Smashing Protector - ProPolice) but it can't detect everything...
01-09-2017 12:47 AM
Usually the way to check stack overflows is using data pattern checking, I mean, write a certain pattern in the stack area of the memory and check if the last byte has been modified. If modified that means that your stack has been overflowed at certain moment of the execution. I would say that same rule can be applied for the HEAP, so try to check it.
Regarding the assert implementations. I guess that if you make use of both the problem would be that he would need to link both library implementations, so will use more memory. So using just one would be preferable from my point of view.