mondinmr - 2025-09-11

Good morning,

I’ve been using the Collection library for a long time, mostly with Stack, LinkedList, and List.
From your examples I was able to manage the different factories, even for custom elements.

Now I need a hashtable, but with this object I’m running into a lot of random access violations.

If I append something inside FB_Init after constructing the hashtable, it crashes, even though the list was already created.

If I only create the hashtable in FB_Init and append afterwards, it usually works.

I don’t understand the meaning of the dispose call in this code:

pSlave := ADR(slave);
uSlave := TO_ULINT(pSlave);
iKey := fKey.Create(uSlave);

IF hash.CountKeys() = 0 THEN
    Service.logger.appendLog('Filling hashtable', 'HashManager', AdvLogType.AdvDebugMsg);
    ok := FALSE;
ELSE
    eError := hash.ContainsKey(iKey, xResult => ok);
END_IF

IF NOT ok THEN
    pI := __NEW(UINT);
    iVal := fKey.Create(TO_ULINT(pI));
    Service.logger.appendLog(CONCAT('New slave', TO_STRING(uSlave)), 'HashManager', AdvLogType.AdvDebugMsg);
    hash.AddKeyValuePair(iKey, iVal);
    appendNewSlave := pI;
ELSE
    eError := hash.GetElementByKey(iKey, itfValue => iElem);
    xResult := __QUERYINTERFACE(iKey, itfIInstance);
    IF xResult THEN
        itfIInstance.Dispose();
    END_IF
    IF eError <> COL.COLLECTION_ERROR.NO_ERROR THEN
        Service.logger.appendLog(CONCAT('ERROR ', TO_STRING(eError)), 'HashManager', AdvLogType.AdvCriticalMsg);
        appendNewSlave := nullptr;
        RETURN;
    END_IF
    __QUERYINTERFACE(iElem, iVal);
    {warning disable C0033}
    pI := TO___UXINT(iVal.UlintValue);
    {warning restore C0033}
    appendNewSlave := pI;
END_IF

Without the dispose call, every second cold reset crashes immediately when I try to access iVal, even if eError doesn’t report any error.

With the dispose call, the cold reset issue disappears, but I get other problems:

a) If I start the runtime using systemctl start codesyscontrol, it crashes at

IF hash.CountKeys() = 0 THEN

b) If I delete the files in PlcLogic and download again, it works and survives multiple cold resets.
But as soon as I run systemctl restart codesyscontrol, everything gets corrupted again and it starts crashing at that point.

FUNCTION_BLOCK SlaveMapCounter
VAR
    hash : COL.IMap2;
    eError : COL.COLLECTION_ERROR;
END_VAR

In its FB_Init I create it:

METHOD FB_Init: BOOL
VAR_INPUT
    bInitRetains: BOOL; // TRUE: retain variables are initialized (reset warm / reset cold)
    bInCopyCode: BOOL;  // TRUE: the instance will be copied to the copy code afterward (online change)   
END_VAR
VAR
    hF : COL.HashTableFactory;
END_VAR

hash := hF.Create(256);

In another FB I instantiate it statically:

FUNCTION_BLOCK ABSTRACT AbstractServoEthercatController EXTENDS AbstractServoController
VAR_STAT    
    hashSlaves : SlaveMapCounter;
END_VAR
VAR
    field : REFERENCE TO ADVAbstractFieldUnitEthercatCia402;
    initCnt : REFERENCE TO UINT;
END_VAR

The append method is the one shown above, and I call it after the runtime has started.

The accesses are performed by a single task, and in any case I’m working on an isolated single core.

I’ve tried everything, moving the create, the instances, and all the rest several times, but nothing seems to work.
I’d like to point out that these FBs are part of our own library, which is used in many applications.

 

Last edit: mondinmr 2025-09-11