EPICS 7 and caput crashes IOC
prjemian opened this issue · comments
-
arch: linux-x86_64
-
base: 7.0.1.1
-
synApps: 5.8
-
optics: 2.13
-
xxx: 5.8.4
-
caput
tobo
record does not crash IOC -
caput
toao
record crashes IOC -
caput
tostringout
record crashes IOC
username@host .../iocBoot/iocLinux $ caput xxx:userStringSeqEnable 1
Old : xxx:userStringSeqEnable Disable
New : xxx:userStringSeqEnable Enable
username@host .../iocBoot/iocLinux $ caput xxx:userStringSeqEnable 0
Old : xxx:userStringSeqEnable Enable
New : xxx:userStringSeqEnable Disable
username@host .../iocBoot/iocLinux $ caget xxx:userCalc1
xxx:userCalc1 0
username@host .../iocBoot/iocLinux $ caget xxx:userCalc1.CALC
xxx:userCalc1.CALC 0
username@host .../iocBoot/iocLinux $ caput xxx:userCalc1.CALC RNDM
Old : xxx:userCalc1.CALC 0
Source File: ../getCopy.cpp line 92
Current Time: Wed Jan 03 2018 21:04:11.327113808
..................................................................
CA.Client.Exception...............................................
Warning: "Virtual circuit disconnect"
Context: "host:5064"
Source File: ../cac.cpp line 1215
Current Time: Wed Jan 03 2018 21:04:11.327049665
..................................................................
CA.Client.Exception...............................................
Warning: "Virtual circuit disconnect"
Context: "op=0, channel=xxx:userCalc1.CALC, type=DBR_TIME_STRING, count=1, ctx="host:5064""
Read operation timed out: PV data was not read.
New : xxx:userCalc1.CALC
username@host .../iocBoot/iocLinux $ caget xxx:userCalc1.A
xxx:userCalc1.A 0
username@host .../iocBoot/iocLinux $ caput xxx:userCalc1.A 0
Old : xxx:userCalc1.A 0
Source File: ../getCopy.cpp line 92
Current Time: Wed Jan 03 2018 21:04:54.946454713
..................................................................
CA.Client.Exception...............................................
Warning: "Virtual circuit disconnect"
Context: "host:5064"
Source File: ../cac.cpp line 1215
Current Time: Wed Jan 03 2018 21:04:54.946385426
..................................................................
CA.Client.Exception...............................................
Warning: "Virtual circuit disconnect"
Context: "op=0, channel=xxx:userCalc1.A, type=DBR_TIME_DOUBLE, count=1, ctx="host:5064""
Read operation timed out: PV data was not read.
New : xxx:userCalc1.A 0
The IOC's console reports:
Segmentation fault
I have reproduced the problem with
/usr/local/epics-devel/base-7.0.1/bin/linux-x86_64/caput xxx:userCalc1.A 0
This is the stack trace:
(gdb) bt
#0 0x00007f28ef65da3d in __strncat_ssse3 () from /lib64/libc.so.6
#1 0x000000000083f071 in my_dbNameOfPV (bufLen=100, paddr=0x7f28904cc568, paddr=0x7f28904cc568, pBuf=0x7f2853efd510 "xxx:userCalc1.A.") at ../caputRecorder.c:266
#2 myAsDataListener (pmessage=0x7f2844018768, after=<optimized out>) at ../caputRecorder.c:309
#3 0x00000000008ebc8e in asTrapWriteAfterWrite (pvt=0x7f2844018758) at ../../src/as/asTrapWrite.c:167
#4 0x00000000008b67ed in write_action (mp=0x7f2853efdd50, pPayload=<optimized out>, client=0x7f2898000f88) at ../../../src/ioc/rsrv/camessage.c:805
#5 0x00000000008b500d in camessage (client=client@entry=0x7f2898000f88) at ../../../src/ioc/rsrv/camessage.c:2538
#6 0x00000000008b1ec0 in camsgtask (pParm=0x7f2898000f88) at ../../../src/ioc/rsrv/camsgtask.c:117
#7 0x000000000090205c in start_routine (arg=0x7f2894001120) at ../../src/osi/os/posix/osdThread.c:403
#8 0x00007f28f07ffe25 in start_thread () from /lib64/libpthread.so.0
#9 0x00007f28ef6bb34d in clone () from /lib64/libc.so.6
(gdb)
The problem is happening in my_dbNameOfPV. But that function is only called if GE_EPICSBASE(3,15,0) is false. Clearly that should be true for base 7.0.1.
It appears to me that the definition of GE_EPICSBASE is incorrect in caputRecorder.c. It is
#define GE_EPICSBASE(v,r,l) ((EPICS_VERSION >= (v)) && (EPICS_REVISION >= (r)) && (EPICS_MODIFICATION >= (l)))
It is using a logical AND, but that seems wrong: if the version is > v then it does not matter what the revision is!
I have fixed the problem with the following patch
corvette:caputRecorder/caputRecorderApp/src>git diff caputRecorder.c
diff --git a/caputRecorderApp/src/caputRecorder.c b/caputRecorderApp/src/caputRecorder.c
index d5a5368..7170fef 100644
--- a/caputRecorderApp/src/caputRecorder.c
+++ b/caputRecorderApp/src/caputRecorder.c
@@ -11,7 +11,13 @@
#include <epicsStdio.h>
#include <epicsThread.h>
#include <epicsVersion.h>
-#define GE_EPICSBASE(v,r,l) ((EPICS_VERSION >= (v)) && (EPICS_REVISION >= (r)) && (EPICS_MODIFICATION >= (l)))
+#ifndef VERSION_INT
+# define VERSION_INT(V,R,M,P) ( ((V)<<24) | ((R)<<16) | ((M)<<8) | (P))
+#endif
+#ifndef EPICS_VERSION_INT
+# define EPICS_VERSION_INT VERSION_INT(EPICS_VERSION, EPICS_REVISION, EPICS_MODIFICATION, EPICS_PATCH_LEVEL)
+#endif
+#define GE_EPICSBASE(v,r,l) (EPICS_VERSION_INT > VERSION_INT(v, r, l, 0))
#if GE_EPICSBASE(3,15,0)
With that patch the caput works correctly:
corvette:~/devel/xxx>/usr/local/epics-devel/base-7.0.1/bin/linux-x86_64/caput xxx:userCalc1.A 0
Old : xxx:userCalc1.A 0
New : xxx:userCalc1.A 0
The patch should be changed slightly to use a similar syntax as lots of other synApps modules:
/* Less than EPICS base version test.*/
#ifndef EPICS_VERSION_INT
#define VERSION_INT(V,R,M,P) ( ((V)<<24) | ((R)<<16) | ((M)<<8) | (P))
#define EPICS_VERSION_INT VERSION_INT(EPICS_VERSION, EPICS_REVISION, EPICS_MODIFICATION, EPICS_PATCH_LEVEL)
#endif
#define GE_EPICSBASE(V,R,M,P) (EPICS_VERSION_INT >= VERSION_INT((V),(R),(M),(P)))
The code will need to be changed slightly to pass a 4'th argument to the macro.
Thanks. I committed a new version of caputRecorder.c with these changes.
confirmed the commit in caputRecorder (hash: 256f57fcc) resolves the error