cryptic error message "parse error: premature EOF"

Bug #1982847 reported by Dirk Zimoch
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
EPICS Base
New
Undecided
Unassigned

Bug Description

In EPICS 7, if an array input link (e.g. waveform.INP) is an explicit empty string, the parser prints a cryptic message without any helpful context.

Example:
record(waveform, "x")
{
    field(INP, "")
}

dbConvertJSON: parse error: premature EOF

                     (right here) ------^

Not very enlightening.

It does not happen if INP is not set at all and it does not happen at least up to R3.16.1 but at least since 7.0.4.1 (I have not tested anything in between) and up to commit d82ab81.
It also does not happen with scalar input links (e.g. ai.INP).

First of all, any parser error should print a context (I prefer record.field) similar to this:
dbConvertJSON: parse error: premature EOF in x.INP

Unfortunately, dbPutConvertJSON (the function printing the dbConvertJSON message) does not have the context. All it has is the string. So maybe it should not print the message at all but leave it to the caller. The only callers are in dbConstLink.c. The interface should be modified to pass either the context (plink instead of plink->value.constantStr) or the error message (which is complicated) or an additional message should be printed by the outer context (difficult to find out when dbPutConvertJSON actually printed an error message).

Second, passing "" should not result in an error at all.

Revision history for this message
Dirk Zimoch (dirk.zimoch) wrote :

Other parser errors are missing context too:
dbConvertJSON: String provided, numeric value(s) expected
What was the string and where did it happen?

Revision history for this message
Dirk Zimoch (dirk.zimoch) wrote :

Hmmm... dbpf calls dbPutConvertJSON too. That makes things more difficult.

Revision history for this message
Dirk Zimoch (dirk.zimoch) wrote :

Can test with dbpf too:
record(waveform, "x")
{
    field(NELM, "2")
    field(FTVL, "DOUBLE")
}

dbpf x ''
dbConvertJSON: parse error: premature EOF

                     (right here) ------^

dbpf x '[]'
DBF_DOUBLE[0]: (empty)

New:
dbpf x ''
DBF_DOUBLE[0]: (empty)
dbpf x '[]'
DBF_DOUBLE[0]: (empty)

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

> ... an array input link (e.g. waveform.INP) is an explicit empty string, the parser prints a cryptic message without any helpful context. ...

From a quick test, this does not seem to be a fatal error. iocInit() succeeds, and the IOC runs as normal. So an annoyance more than an impediment.

> Not very enlightening.

I agree.

Your patch looks reasonable.

@anj, Compared with eg. dbGet(), it looks like pnRequest can never be NULL. Am I reading this correctly?

Revision history for this message
Dirk Zimoch (dirk.zimoch) wrote :
Revision history for this message
Dirk Zimoch (dirk.zimoch) wrote :

I have added some context to the messages:

dbConvertJSON: String provided, numeric value(s) expected
...while parsing link x.INP ["x"]

dbConvertJSON: Embedded arrays not supported
...while parsing link x.INP [[]]

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

@mdavidsave correct, pnRequest must never be NULL since (unless you pass in a bad dbrType) it will always be dereferenced to populate parser->elems and will be written to if the parse succeeds.

Could the two "if (status == S_db_badField)" tests in dbConstLink.c become just "if (status)" please, since we'd almost certainly want the same context message to be printed for any other error status values get returned from the same routine. Add a space after the ellipsis in each message perhaps?

With those suggestions this looks good to me, thanks!

Revision history for this message
Dirk Zimoch (dirk.zimoch) wrote :

The other cases (e.g. out of memory) should then print something too. Otherwise … while parsing xxxx would look a bit lost.

Revision history for this message
Dirk Zimoch (dirk.zimoch) wrote :

> Could the two "if (status == S_db_badField)" tests in dbConstLink.c become just "if (status)" please, [...] Add a space after the ellipsis in each message perhaps?

Done.

Revision history for this message
Dirk Zimoch (dirk.zimoch) wrote :

Working on proper errors for the other cases now. Which of the following two formats would you prefer?

dbConvertJSON: Null objects not supported
... while parsing link w9.INP [null]
dbConvertJSON: String "text" provided, numeric value expected
... while parsing link w10.INP ["text"]

or

dbConvertJSON: Null objects not supported
dbConvertJSON: parse error: client cancelled parse via callback return value
                                   [null]
                     (right here) ------^
... while parsing link w9.INP
dbConvertJSON: String "text" provided, numeric value expected
dbConvertJSON: parse error: client cancelled parse via callback return value
                                 ["text"]
                     (right here) ------^
... while parsing link w10.INP

Revision history for this message
Dirk Zimoch (dirk.zimoch) wrote :

Can anyone tell me how to trigger dbLSConvertJSON()?
I tried record(lsi,x){field(INP,{const: "Text"})} and it calls dbLoadLinkLS but not dbConstLoadLS as I had expected and thus not dbLSConvertJSON.

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

linkInitTest covers dbLSConvertJSON()

From modules/database/test/std/reclinkInitTest.db

> record(lsi, "longstr1") {
> field(SIZV, "100")
> field(INP, ["!----------------------------------------------!"])
> }

If it helps, it took me awhile to figure this out again. The distinction between the the "const" link suppport, and constant link syntax still tricks me.

Revision history for this message
Dirk Zimoch (dirk.zimoch) wrote :

Thanks.
Why does field(INP, ["Text1","Text2","Text3"]) not raise an error? Is that how it is supposed to be? (The record has the value "Text1" in this case.)

Revision history for this message
Dirk Zimoch (dirk.zimoch) wrote :

I have added some error messages and streamlined the code.
Take the latest commit as a suggestion...

Revision history for this message
Dirk Zimoch (dirk.zimoch) wrote :

record(lsi, "lsi1")
{
    field(INP, ["Some text",0x7,9.2,"more text"])
}
record(waveform, "wf1")
{
    field(FTVL, CHAR)
    field(NELM, 100)
    field(INP, ["Some text",0x7,9.2,"more text."])
}

epics> dbgf lsi1
DBF_STRING: "Some text\a\tmore text"
pc12708> dbgf wf1
DBF_CHAR[21]: "Some text more text."

Revision history for this message
Dirk Zimoch (dirk.zimoch) wrote :

These are some error messages:
dbConvertJSON: Null objects not supported
dbConvertJSON: parse error: client cancelled parse via callback return value
                                   [null]
                     (right here) ------^
... while parsing link lsi4.INP
dbConvertJSON: Boolean not supported
dbConvertJSON: parse error: client cancelled parse via callback return value
                                   [true]
                     (right here) ------^
... while parsing link lsi5.INP
dbConvertJSON: Embedded arrays not supported
dbConvertJSON: parse error: client cancelled parse via callback return value
                                      [[]]
                     (right here) ------^
... while parsing link lsi7.INP
dbConvertJSON: Map type not supported
dbConvertJSON: parse error: client cancelled parse via callback return value
                                      [{}]
                     (right here) ------^
... while parsing link lsi8.INP
dbConvertJSON: Embedded arrays not supported
dbConvertJSON: parse error: client cancelled parse via callback return value
                                      [[]]
                     (right here) ------^
... while parsing link w5.INP
dbConvertJSON: Map type not supported
dbConvertJSON: parse error: client cancelled parse via callback return value
                                      [{a:1}]
                     (right here) ------^
... while parsing link w6.INP
dbConvertJSON: Boolean not supported
dbConvertJSON: parse error: client cancelled parse via callback return value
                               [0,1,true,false,4]
                     (right here) ------^
... while parsing link w7.INP
dbConvertJSON: Boolean not supported
dbConvertJSON: parse error: client cancelled parse via callback return value
                                  [false,null,"text",0,1,true]
                     (right here) ------^
... while parsing link w8.INP
dbConvertJSON: Null objects not supported
dbConvertJSON: parse error: client cancelled parse via callback return value
                                   [null]
                     (right here) ------^
... while parsing link w9.INP
dbConvertJSON: String "text" provided, numeric value expected
dbConvertJSON: parse error: client cancelled parse via callback return value
                                 ["text"]
                     (right here) ------^
... while parsing link w10.INP

Revision history for this message
Dirk Zimoch (dirk.zimoch) wrote :

Fixed dbgf output (actually printBuffer(), used by dbgf, dbtgf, and dbtpf) to use epicsStrnEscapedFromRaw on CHAR[] output.

Example:
record(waveform, "wf1")
{
    field(FTVL, CHAR)
    field(NELM, 500)
    field(INP, ["Lorem ipsum dolor sit amet,",
        " consetetur sadipscing elitr,", 7, 255,
        " sed diam nonumy eirmod tempor invidunt", 9,
        " ut labore et dolore magna aliquyam erat,", 10,
        " sed diam voluptua. At vero eos et accusam", 11,
        " et justo duo dolores et ea rebum.", 12,
        " Stet clita kasd gubergren,", 13,
        " no sea takimata sanctus est Lorem ipsum dolor sit amet."])
}

Before:
epics> dbgf wf1
DBF_CHAR[302]:
"Lorem ipsum dolor sit amet, consetetur sadipscing elitr,� sed diam nonumy " +
"eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
 sed diam " +
"voluptua. At vero eos et accusam
                                  et justo duo dolores et ea rebum.
                                                                    Stet c" +
 no sea takimata sanctus est Lorem ipsum dolor sit ame" +
"t."

Now:
epics> dbgf wf1
DBF_CHAR[302]:
"Lorem ipsum dolor sit amet, consetetur sadipscing elitr,\a\xff sed diam no" +
"numy eirmod tempor invidunt\t ut labore et dolore magna aliquyam erat,\n s" +
"ed diam voluptua. At vero eos et accusam\v et justo duo dolores et ea rebu" +
"m.\f Stet clita kasd gubergren,\r no sea takimata sanctus est Lorem ipsum " +
"dolor sit amet."

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.