Setting NAME field in DB file may break IOC

Bug #1597809 reported by Ralph Lange
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
EPICS Base
Status tracked in 7.0
3.14
Fix Released
Undecided
Unassigned
3.15
Fix Released
Undecided
Unassigned
3.16
Fix Released
Undecided
Unassigned
7.0
Fix Released
Undecided
Andrew Johnson

Bug Description

The Database runtime prevents SPC_NOMOD fields from being written to when the database is running.

However, during DB file parsing, this mechanism is not active, and such fields are set to the value from the database file.

In the case of

record(ai, "foo") {
  field(NAME, "bar")
}

This leads to a situation where

    > softIoc -d test-name.db
    Starting iocInit
    ############################################################################
    ## EPICS R3.15.4 $$Date$$
    ## EPICS Base built Jun 14 2016
    ############################################################################
    iocRun: All initialization complete
    epics> dbl
    bar
    epics> dbpr foo
    PV 'foo' not found
    epics> dbpr bar
    PV 'bar' not found
    epics>

Channel Access also doesn't find the record.

When using an ASYN driver, we have seen IOCs segfault when the field NAME was set to a string containing invalid characters (an ampersand '&' in our case).

Should we disallow setting SPC_NOMOD fields from database files?
Should we silently ignore them? Print warnings?
Or should setting the NAME field call dbRenameRecord() instead of dbPutString()?

Revision history for this message
Martin Konrad (info-martin-konrad) wrote :

I can't think of any use case were modifying a SPC_NOMOD field would make sense. I think disallowing writes to these fields at database-load time would make sense.

Side-note: The Record Reference Manual says DTYP can NOT be modified (https://wiki-ext.aps.anl.gov/epics/index.php/RRM_3-14_dbCommon#Field_Summary_5) while dbCommon.dbd lists DTYP without "special(SPC_NOMOD)"? Am I missing something or is the Wiki wrong here?

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

Yup, changing NAME is a good way to break things. This changes dbCommon::name but not dbRecordNode::recordname nor the entry in the hash table of record names.

> I can't think of any use case were modifying a SPC_NOMOD field would make sense.

NELM and FTVL come immediately to mind.

> DTYP can NOT be modified ... Am I missing something or is the Wiki wrong here?

This inconsistency likely dates from the addition of the the somewhat esoteric extended device support feature, which allows changing DTYP. see 'struct dsxt' in devSup.h. mrfioc2 makes use of this.

Revision history for this message
Andrew Johnson (anj) wrote :

Unless this is an alias dbRecordNode::recordname should be a pointer to dbCommon::name (we only free that storage when DBRN_FLAGS_ISALIAS is set). The reason changing the NAME field causes subsequent PV lookups to fail is that the record is now in the wrong gpHash bucket.

We do have to allow writes to SPC_NOMOD fields when loading the database, as Michael pointed out fields like NEML and FTVL are design fields that are SPC_NOMOD and we have to be able to set them during DB file parsing. The Wiki is out of date, fixes welcome (I can create an account for anyone who doesn't have one).

I would disallow writing to NAME in dbRecordField() in dbLexRoutines.c but strcmp() isn't the quickest way to identify the situation; NAME always has a field index of zero, so here's my fix to 3.14 which should merge up cleanly:

diff --git a/src/dbStatic/dbLexRoutines.c b/src/dbStatic/dbLexRoutines.c
index db95cc6..f9c2f8e 100644
--- a/src/dbStatic/dbLexRoutines.c
+++ b/src/dbStatic/dbLexRoutines.c
@@ -974,6 +974,12 @@ static void dbRecordField(char *name,char *value)
        yyerror(NULL);
        return;
     }
+ if (pdbentry->indfield == 0) {
+ epicsPrintf("Can't set \"NAME\" field of record \"%s\"\n",
+ dbGetRecordName(pdbentry));
+ yyerror(NULL);
+ return;
+ }
     dbTranslateEscape(value, value); /* yuck: in-place, but safe */
     status = dbPutString(pdbentry,value);
     if(status) {

Changed in epics-base:
assignee: nobody → Andrew Johnson (anj)
status: New → In Progress
Revision history for this message
Ralph Lange (ralph-lange) wrote :

Looks good to me.
(On my phone, so by visual inspection only.)

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.