epics-modules / xxx

APS BCDA synApps module: xxx

Home Page:http://epics-modules.github.io/xxx

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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 to bo record does not crash IOC

  • caput to ao record crashes IOC

  • caput to stringout 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