IOC crashes for DBR_CTRL_CHAR request with 1 array element
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
EPICS Base |
Fix Released
|
High
|
mdavidsaver | ||
3.14 |
Invalid
|
Undecided
|
Unassigned | ||
3.15 |
Fix Released
|
High
|
mdavidsaver | ||
3.16 |
Fix Released
|
High
|
mdavidsaver |
Bug Description
http://
On 04/01/2017 09:20 AM, Kasemir, Kay wrote:
> Hi:
>
>
> When reading a "long string" PV as DBR_CTRL_CHAR with 1 array element,
> an EPICS 3.15.5 IOC crashes.
>
> Has been OK with R3.14.x.
>
>
> Example C client and stack trace of server is below. Basically, CA
> server seems to try return all elements of the CHAR array, but the
> buffer only allows for the 1 requested.
>
>
> Why I ran into this:
>
> Older IOCs, i.e. most of those in operation ;-), don't support
> DBE_PROPERTY.
>
> So clients fetch the DBR_CTRL_
> for example DBR_STS_* for the complete array.
>
> When fetching the initial meta data, they don't need the complete value.
> In fact for large arrays it would be wasteful to keep a copy of the
> whole outdated array, just need the meta data and then one instance of
> the 'current' array.
>
>
> Thanks,
>
> Kay
>
>
> Example C code that crashes IOC:
> ````
> /* USAGE: cademo SomePV.INP$
> *
> * Fetches a "long string" channel as DBR_CTRL_CHAR[1].
> * OK for R4.14.*, crashes R3.15.5
> */
> #include <stdio.h>
> #include <string.h>
> #include <epicsStdlib.h>
> #include <epicsString.h>
> #include <cadef.h>
>
> int main (int argc, char *argv[])
> {
> const char *name = argv[1];
> int result;
> chid chid;
> struct dbr_ctrl_char value;
>
> puts(name);
>
> result = ca_context_
> SEVCHK(result, "connect");
> result = ca_create_
> SEVCHK(result, "create");
> result = ca_pend_io(2.0);
> SEVCHK(result, "pend create");
> result = ca_array_
> SEVCHK(result, "get");
> result = ca_pend_io(2.0);
> SEVCHK(result, "pend get");
>
> ca_context_
>
> return result;
> }
> ````
>
> For an IOC created via `makeBaseApp.pl -t example`, when reading
> `$(user):ai1.INP$`, the IOC crashes while placing the value,
> `$(user)
> ````
> Program received signal SIGSEGV, Segmentation fault.
> [Switching to Thread 0x7fffd75f8700 (LWP 4974)]
> 0x00007ffff66eb795 in __strncpy_
> Missing separate debuginfos, use: debuginfo-install
> glibc-2.
> libstdc+
> readline-
> (gdb) bt
> #0 0x00007ffff66eb795 in __strncpy_
> #1 0x00007ffff7735ebf in getLinkValue (paddr=
> paddr=0x7fffe40
> nRequest=<optimized out>, pbuf=0x7ffff7e53035
> "training:
> dbrType=<optimized out>) at ../../.
> #2 dbGet (paddr=
> pbuffer=<optimized out>,
> options=
> nRequest=
> pflin=pflin@
> #3 0x00007ffff773888c in dbChannelGet (chan=chan@
> type=type@entry=2,
> pbuffer=<optimized out>, options=
> nRequest=
> at ../../.
> #4 0x00007ffff774b8d3 in dbChannel_get_count
> (chan=chan@
> buffer_
> nRequest=
> pfl=pfl@entry=0x0) at ../../.
> #5 0x00007ffff776f6c2 in read_reply (pfl=0x0, eventsRemaining=1,
> dbch=0x7fffe401
> pArg=0x7fffd75f
> #6 read_notify_action (mp=<optimized out>, pPayload=<optimized out>,
> client=<optimized out>)
> at ../../.
> #7 0x00007ffff77708df in camessage (client=
> at ../../.
> #8 0x00007ffff776d26c in camsgtask (pParm=
> at ../../.
> #9 0x00007ffff727a58c in start_routine (arg=0x7fffe000
> at ../../.
> #10 0x00007ffff6441dc5 in start_thread () from /lib64/
> #11 0x00007ffff674d73d in clone () from /lib64/libc.so.6
> ````
This is quite easy to reproduce.
> $ cat <<EOF > test.db x86_64- debug/softIoc -d test.db
> record(calc, "cnt") {
> field(INPA, "cnt")
> field(CALC, "A+1")
> field(SCAN, "1 second")
> }
> EOF
> $ ./bin/linux-
then in another shell run
> $ caget -# 1 -d CTRL_CHAR cnt.INPA