Regression in calcout setting constant links at runtime
Affects | Status | Importance | Assigned to | Milestone | ||
---|---|---|---|---|---|---|
EPICS Base | Status tracked in 7.0 | |||||
7.0 |
In Progress
|
High
|
Andrew Johnson |
Bug Description
With the 3.15 branch, writing a literal number to a calcout.INP[A-L] field causes the corresponding [A-L] field to be set to that number. This works because the calcout record marks the INP fields as special(SPC_MOD) and the calcout::special() routine calls recGblInitConst
Keenan Lang reported that this doesn't currently work on the 7.0 branch; the value in the [A-L] field doesn't change, which I have confirmed.
This use of special() to reinitialize constant links is unusual, normally putting a literal into a link field after record initialization has no effect, but someone who worked on the calcout record discovered this way to get it to work.
I think I know what's going on and how to fix it (change dbPutFieldLink() to call dbAddLink() before the second call to dbPutSpecial()), but I need to check that this won't break other cases.
Related branches
- Andrew Johnson: Needs Fixing
- mdavidsaver: Needs Fixing
-
Diff: 317 lines (+133/-20)12 files modifieddocumentation/RELEASE_NOTES.html (+12/-0)
modules/database/src/ioc/db/dbAccess.c (+36/-10)
modules/database/src/std/dev/devAiSoftCallback.c (+1/-1)
modules/database/src/std/dev/devBiSoftCallback.c (+1/-1)
modules/database/src/std/dev/devI64inSoftCallback.c (+1/-1)
modules/database/src/std/dev/devLiSoftCallback.c (+1/-1)
modules/database/src/std/dev/devMbbiDirectSoftCallback.c (+1/-1)
modules/database/src/std/dev/devMbbiSoftCallback.c (+1/-1)
modules/database/src/std/dev/devSiSoftCallback.c (+1/-1)
modules/database/test/std/rec/Makefile (+2/-2)
modules/database/test/std/rec/regressCalcout.db (+27/-0)
modules/database/test/std/rec/regressTest.c (+49/-1)
Tricky issue, not quite as simple as I thought it would be.
I first wrote a regression test program which demonstrates the regression 4 times using a calcout record by putting different strings into its INP* fields and looking at the * and IN*V field values that resulted.
To fix it I created a fix that makes dbAccess.c's dbPutFieldLink() routine call dbAddLink() before the second dbPutSpecial() when the new link type is CONSTANT, PV_LINK or JSON_LINK, instead of lower down. This change fixes the bug, but unfortunately breaks the initialization of the dev*softCallback device supports, because they expect their add_record() routines to be called before dbAddLink() resolves a PV_LINK into either a DB_LINK or CA_LINK (they turn it into a PN_LINK instead).
I can resolve the CONSTANT or JSON_LINK types before the second dbPutSpecial(), but the calcout record's special() routine still notices the difference for DB and CA links because it calculates a new INAV field value, and if that happens before dbAddLink() gets called it's going to give the wrong result for them.
I need to back-port my regression test to 3.15 and 3.14 (or run it by hand) to confirm what broke when before I commit anything.