1

I'm trying to build a composite pattern in Twincat 3.1.

Everything seems to work fine on Activate Configuration and the first new download or online change. The second new download causes General Protection Error or BSOD, no matter how many objects I add or remove.

For simplicity, Object is FB implementing the I_SYS_COMP_Object interface.

The project uses FB_init and FB_exit to add or remove objects from the global object list. Previous iterations used call_after_init attributes with the same result.

As the code became lengthy, I'm adding a link to the repository. GitHub rep

How should I approach this kind of issue?

Edit 26/11:

Core dump and exception mode don't work.

So far, I have found that:

IF object <> 0 THEN 
    RETURN; 
END_IF 
_this_object = THIS^; 
IF object.parent <> THIS^ THEN 
    RETURN;
END_IF 

was part of the problem. Now I'm getting BSOD a few lines below, at

_last_child := object; 

Which is strange as this should be a straightforward assignment. Currently, _last_child is used only in the problematic method. I put a RETURN; straight after the assignment, but I'm still getting BSOD.

Krystian
  • 11
  • 2
  • I've sometimes used bi-sectional search to find obscure issues. I disable half the tasks, run them, in case the issue disappears, disable the other half. Once you're left with a single task, I would comment out half the code, run it again and depending on the result comment out half of the remaining or uncomment part of the commented code. Does it go into exception mode (yelllow runtime icon) and if you log in can you see the part where it failed? Or are [core dumps](https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_plc_intro/6884133515.html&id=) created? – Roald Nov 25 '22 at 19:15
  • Exception mode doesn't work, and it looks like the core dump file is corrupted. – Krystian Nov 26 '22 at 09:39
  • So far, I have found that: IF object <> 0 THEN RETURN; END_IF _this_object = THIS^; IF object.parent <> THIS^ THEN RETURN; END_IF was part of the problem. Now I'm getting BSOD a few lines below at: _last_child := object; Which is strange as this should be a straightforward assignment. – Krystian Nov 26 '22 at 09:46
  • Tricky. Another idea would be to enable [Implicit checks](https://infosys.beckhoff.com/content/1033/tc3_plc_intro/2530351499.html?id=3677405530121520990). – Roald Nov 28 '22 at 07:14
  • @Roald If a FB is assigned to the interface and then deleted, Twincat doesn't 0 the interface. The interface then can pass through <> 0 checks but will throw an error when used. It is hard to troubleshoot as it all happens during FB_init and FB_exit stages. I think I need to refactor this project. – Krystian Nov 28 '22 at 10:44

1 Answers1

0

I cannot provide specific guidance regarding your issue, but my experience is debugging code called from FB_Init is extremely frustrating because you cannot step into the code.

I have therefore developed an approach where I use FB_Init for very simple things (mostly assignments, often REF= assignments) and delaying actual initialization code until after FB_Init methods have been called. I implemented my own, separate, initialization and execution framework which makes this easy. I am losing my hair at a slower pace thanks to this approach.

I use assertions a lot (especially preconditions in methods, including FB_Init), and I crash the runtime when observing an out-of-spec situation. I check them in FB_Init calls, but the framework actually delays crashing until normal execution begins. That way, I am not losing information about the reason for the crash as I would if it were to happen during FB_Init execution. Catching invalid references passed to FB_Init is one frequent case where this saves a lot of aggravation.

Fred
  • 6,590
  • 9
  • 20
  • I'm using FB_init and FB_exit to remove/add the interface from or to the global array. The code seems to crash even without them in the build. It is strange because everything works just fine as long as I'm not doing online change. – Krystian Nov 25 '22 at 17:11
  • I have read about how FB_Init is called in case of online change / warm reset / cold reset in the past, but this is not something I have top of mind at the moment. Maybe some pointer/reference is cleared, or some array index you expect to be cleared is actually kept and your array items do not end up where you expect them to. That being said, aside from progressively removing things from your code until you are able to isolate the offending code, I have no way to deal with that. Hence my quite strict avoidance of non-trivial code in FB_Init methods. – Fred Nov 26 '22 at 18:14