What causes the dynamically allocated error messages in Twincat 4024 and how do I get rid of them?

Viewed 669

We have a project which was made with 4022.29 originally. We also tried to run the project with TwinCAT 4024.x. When the configuration is activated for the first time on my local machine it runs fine. However, when I restart the project or activate the configuration I get the following error messages:

Error                      27.08.2019 14:06:37 322 ms | 'Port_851' (851): PLC: PLC instance xxx Instance tried to free pointer 0xffff9e02fe620bd8 which was not allocated by the PLC instance.                                                              
Error                      27.08.2019 14:06:37 322 ms | 'Port_851' (851): PLC: PLC instance xxx Instance tried to free pointer 0xffff9e02fe620b48 which was not allocated by the PLC instance.                                                              
… (~20 more error messages)                                                                                                     
Error                      27.08.2019 14:06:37 322 ms | 'Port_851' (851): PLC: PLC instance xxx Instance tried to free pointer 0xffff9e02fe61fe28 which was not allocated by the PLC instance.                                                               
Error                      27.08.2019 14:06:37 322 ms | 'Port_851' (851): PLC: PLC instance xxx Instance did not free dynamically allocated memory block at address 0xffff9e02fe616878 of size 65.                                                  
Error                      27.08.2019 14:06:37 322 ms | 'Port_851' (851): PLC: PLC instance xxx Instance did not free dynamically allocated memory block at address 0xffff9e02fe6167d8 of size 65.                                                  
… (~20 more error messages)                                                                     
Error                      27.08.2019 14:06:37 322 ms | 'Port_851' (851): PLC: PLC instance xxx Instance did not free dynamically allocated memory block at address 0xffff9e02fe615978 of size 55.  

What causes these error messages? Why do they suddenly show up? Should I get rid of them and if yes how do I do it?

2 Answers

Partial answer

This answer can use some improvements/better understanding. I'll post it here to collect some information on the solutions.

Origin

From Beckhoff support:

The error messages you receive lead to dynamically allocated memory in the router memory (such as __new() ) or not released interface pointers.

The mentioned error messages were implemented with the 4024 release. In the older versions of TwinCAT we were not able to detect such a memory lack.

How I got rid of them

I am not quite sure how to put the above in my own words due to lack of understanding. However, I did track down the origin of the error messages in our project.

Binary search

What I did is to use binary search to track down the origin of the issue. First I kept disabling half of the active tasks of the project until the error message disappeared. Then I re-enabled tasks until I had the specific task causing the issue. After that I did the same with the code running in this task. En/disabling the remaining 50% to track down the code causing the issues.

Origin

In the end I found a function block which used other function blocks as its input. When I changed the inputs from

VAR_INPUT
    fbSomeFb : FB_SomeFB;
END_VAR

into

VAR_INPUT
    fbSomeFb : REFERENCE TO FB_SomeFB;
END_VAR

the error messages disappeared when the project was restarted.

Fixed another issue

After getting rid of these error messages, another issue with this particular project was solved. We always had the issue that the PLC crashed and restarted when we activated a configuration, or put in into config mode. This only happened on the machine PLC (not any of our development PLCs).

You allocated memory on the heap for an object using the __NEW function. You need to deallocate it. In dynamic programming you need to deallocate an object after you're done using it. The way to do it in TwinCAT is to use the __DELETE function.

If you're using __NEW in a Function Block (FB), you can simply deallocate the object in the FB_Exit(...) method by calling the __DELETE function there.

e.g. In FB_Init(...) you put:

pData := __NEW(INT);

In FB_Exit(...) you put:

__DELETE(pData);

FB_Exit(...) will be called whenever you FB moves out of scope. This will automatically deallocate the object from memory.

If you dont want to use FB_Exit(...) you need to think carefully about the conditions necessary for your program to deallocate the object you created from memory.

Related