Giter Site home page Giter Site logo

epics-base / epics-base Goto Github PK

View Code? Open in Web Editor NEW
123.0 123.0 133.0 103.5 MB

The C/C++ core of the EPICS Base control system toolkit

Home Page: https://epics-controls.org/

License: Other

Makefile 1.57% HTML 3.77% C 66.45% Perl 4.50% Shell 0.18% CSS 0.08% Batchfile 0.11% C++ 22.00% XS 0.53% Lex 0.11% Yacc 0.63% Smalltalk 0.01% Python 0.08%

epics-base's Introduction

---------------------------------------------------------
EPICS Base - the central core of a control system toolkit
---------------------------------------------------------

Copyright UChicago Argonne LLC, as Operator of Argonne
National Laboratory.
Copyright (c) 1991-2003 The Regents of the University of
California, as Operator of Los Alamos National Laboratory.

EPICS Base is distributed subject to a Software License
Agreement found in the file LICENSE that is included with
this distribution.

---------------------------------------------------------

Installation and release information can be found in the
various files in the documentation subdirectory.

Additional information about EPICS including mailing list
archives and subscription instructions, documentation and
training materials, additional components, links to other
websites etc. is available on the EPICS home page at
	https://epics.anl.gov/

$Format:%cD$
$Format:%H$
https://code.launchpad.net/epics-base

epics-base's People

Contributors

abjectfailure avatar anjohnson avatar araneidae avatar bfrk avatar bhill-slac avatar dirk-zimoch avatar echandler-anl avatar ericonr avatar exzombie avatar freddieakeroyd avatar gabrielfedel avatar hanlet avatar hjunkes avatar jeffreyohill avatar jjl772 avatar jlmuir avatar joaopaulosm avatar johnnytang1218 avatar mark0n avatar mdavidsaver avatar minijackson avatar mrkraimer avatar niamhdougan avatar norumwe12 avatar ralphlange avatar ronaldomercado avatar rtsoliday avatar simon-ess avatar tboegi avatar till-s avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

epics-base's Issues

Client using ca_enable_preemptive_callback gets no monitor updates

I have a CA client using ca_enable_preemptive_callback. The ca_create_subscription is called and events received. If I call ca_clear_subscription and ca_create_subscription again monitor events do not arrive anymore.

I realized that calling ca_poll after second ca_create_subscription solves the issue for me.

Bug or feature?

In my client code I do not have any calls to to ca_poll, ca_pend_io or ca_pend_event anywhere because magic.

code:
caMonitor.txt

EPICS base R7.0.6.1.

[PATCH] Allow the IOC to use a specified TCP port while keeping UDP port 5064

diff -ur base-7.0.3-orig/modules/database/src/ioc/rsrv/caservertask.c base-7.0.3/modules/database/src/ioc/rsrv/caservertask.c
--- base-7.0.3-orig/modules/database/src/ioc/rsrv/caservertask.c	2019-08-01 01:11:22.000000000 +0800
+++ base-7.0.3/modules/database/src/ioc/rsrv/caservertask.c	2020-04-16 21:20:56.272178932 +0800
@@ -582,6 +582,10 @@
     }
 
     {
+        if ( envGetConfigParamPtr ( &EPICS_CAS_TCP_PORT ) ) {
+            ca_server_port = envGetInetPortConfigParam ( &EPICS_CAS_TCP_PORT,
+                (unsigned short) CA_SERVER_PORT );
+        }
         unsigned short sport = ca_server_port;
         socks = rsrv_grab_tcp(&sport);
 
diff -ur base-7.0.3-orig/modules/libcom/src/env/envDefs.h base-7.0.3/modules/libcom/src/env/envDefs.h
--- base-7.0.3-orig/modules/libcom/src/env/envDefs.h	2019-08-01 01:11:22.000000000 +0800
+++ base-7.0.3/modules/libcom/src/env/envDefs.h	2020-04-16 21:20:56.273178940 +0800
@@ -57,6 +57,7 @@
 epicsShareExtern const ENV_PARAM EPICS_CAS_AUTO_BEACON_ADDR_LIST;
 epicsShareExtern const ENV_PARAM EPICS_CAS_BEACON_ADDR_LIST;
 epicsShareExtern const ENV_PARAM EPICS_CAS_SERVER_PORT;
+epicsShareExtern const ENV_PARAM EPICS_CAS_TCP_PORT; /* non-standard */
 epicsShareExtern const ENV_PARAM EPICS_CA_BEACON_PERIOD; /* deprecated */
 epicsShareExtern const ENV_PARAM EPICS_CAS_BEACON_PERIOD;
 epicsShareExtern const ENV_PARAM EPICS_CAS_BEACON_PORT;

(For EPICS v3, change modules/database/src/ioc/rsrv/caservertask.c to src/ioc/rsrv/caservertask.c, and modules/libcom/src/env/envDefs.h to src/libCom/env/envDefs.h.)

With this patch, we can configure multiple IOCs on a same host to use pre-determined TCP ports while sharing UDP port 5064, making it easier to specify firewall rules. Following is a little wrapper script that helps to start the IOCs with automatically increasing TCP port number.

#!/bin/sh
# Usage (remember to run `rm -f /tmp/ioc.*' on machine shutdown):
#   EPICS_CAS_TCP_PORT=$( \
#       flock /tmp/ioc.lock /path/to/wrapper /tmp/ioc.port \
#   ) ../../bin/linux-x86_64/someApp st.cmd

[ -s "$1" ] || echo 5066 > "$1"
port=$(cat "$1")
expr "$port" + 1 > "$1"
echo "$port"

Issue with long string `CALC$`

Originating with https://epics.anl.gov/tech-talk/2021/msg01491.php

Test case from https://epics.anl.gov/tech-talk/2021/msg01504.php

record(calc, "test_calc")
{
    field(SCAN, "1 second")
    field(CALC, "RNDM*100")
}

$ caget -S test_calc.CALC$
test_calc.CALC$ RNDM*100

$ caput -S test_calc.CALC$ "300"
Old : test_calc.CALC$ RNDM*100
CA.Client.Exception...............................................
    Warning: "Channel write request failed"
    Context: "op=1, channel=test_calc.CALC$, type=DBR_CHAR, count=4, ctx="test_calc""
    Source File: ../oldChannelNotify.cpp line 159
    Current Time: Sat Aug 07 2021 15:27:54.755166000
..................................................................
New : test_calc.CALC$ 3NDM*100

.. and the softIoc shows this error:

Illegal field value PV: test_calc calc: Illegal CALC field
test_calc.CALC: Syntax error, unknown operator/operand in expression "3NDM*100"

Improvements to EPICS_DEPRECATED?

It would be nice to have a standard way to suppress EPICS_DEPRECATED warnings in places that we can't remove — IIRC test code and implementations of member functions in a derived class are places that are unavoidable for example.

Recently-deprecated epicsThreadExitMain() is used by i-Tech Libera IOC code

We just rebuilt the IOC for one or our Libera devices, updating from Base 7.0.4 to 7.0.6.1 which broke the IOC (running on Ubuntu 18.04, x86_64).

Their software calls epicsThreadExitMain() at the end of some code that I suspect is processing records in their own threads, the C++ symbol istd::thread::thread_fnc(void*) appears below but I believe there's tail-call optimization going on, I have the source for the call which appears at the end of a different more application-specific function.

We can change their code, but my guess is that they are calling this to free up thread-specific resources that the IOC is allocating. Given the frequency of the message repeats I suspect their threads are short-lived, so they need some call to release the stuff we allocate in createImplicit(), and I don't see any other API we provide which can do that.

Can we undeprecate this, or provide some other way of undoing createImplicit()? I do see that as a legitimate need.

iocInit
Starting iocInit
############################################################################
## EPICS R7.0.6.1-C2-1
## Rev. 7.0.6.1-C2-1
############################################################################
iocRun: All initialization complete
## Do iocStd post-initialization
< "/C2/ioc-modules/build/IOCSTD/4.1.0-C2-1+LIB-003/bin/linux-x86_64/postInit.iocsh"
# iocStdPostInit
#<aoi name="aoi_site_controls_iocstd_ioc-data-dump">
# Record our boot parameters
stdPrtBootParam "/C2/iocinfo/bootparams/sioc2k2llrf"
# Log the reboot time and reason
rebootLog "/C2/iocinfo/bootlog/sioc2k2llrf",1
epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.
Thread non-EPICS_140536976410368 (0x7fd0fc002020) can't proceed, suspending.
Dumping a stack trace of thread 'non-EPICS_140536976410368':
epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.Thread non-EPICS_140536974305024 (0x7fd1000026d0) can't proceed, suspending.
epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.Thread non-EPICS_140536970094336 (0x7fd0f0002640) can't proceed, suspending.
epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.Thread non-EPICS_140535820953344 (0x7fd0c0002a60) can't proceed, suspending.
epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.Thread non-EPICS_140536972199680 (0x7fd0f80018e0) can't proceed, suspending.
epicsThreadExitMain() has been deprecated for lack of usage.  Please report if you see this message.errlog: 77 messages were discarded
[    0x559e03ab28f3]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(epicsStackTrace+0x73)
[    0x559e03aa54c5]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(cantProceed+0xc5)
[    0x559e03aafce6]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(epicsThreadExitMain+0x56)
[    0x7fd15d189ebc]: /opt/libera/lib/libliberaistd.so.3.16(_ZN4istd6thread10thread_fncEPv+0x1c)
[    0x7fd15b8416db]: /lib/x86_64-linux-gnu/libpthread.so.0(start_thread+0xdb)
[    0x7fd15a5d6a3f]: /lib/x86_64-linux-gnu/libc.so.6(clone+0x3f)
Dumping a stack trace of thread 'non-EPICS_140536974305024':
[    0x559e03ab28f3]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(epicsStackTrace+0x73)
[    0x559e03aa54c5]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(cantProceed+0xc5)
[    0x559e03aafce6]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(epicsThreadExitMain+0x56)
[    0x7fd15d189ebc]: /opt/libera/lib/libliberaistd.so.3.16(_ZN4istd6thread10thread_fncEPv+0x1c)
[    0x7fd15b8416db]: /lib/x86_64-linux-gnu/libpthread.so.0(start_thread+0xdb)
[    0x7fd15a5d6a3f]: /lib/x86_64-linux-gnu/libc.so.6(clone+0x3f)
Dumping a stack trace of thread 'non-EPICS_140536970094336':
[    0x559e03ab28f3]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(epicsStackTrace+0x73)
[    0x559e03aa54c5]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(cantProceed+0xc5)
[    0x559e03aafce6]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(epicsThreadExitMain+0x56)
[    0x7fd15d189ebc]: /opt/libera/lib/libliberaistd.so.3.16(_ZN4istd6thread10thread_fncEPv+0x1c)
[    0x7fd15b8416db]: /lib/x86_64-linux-gnu/libpthread.so.0(start_thread+0xdb)
[    0x7fd15a5d6a3f]: /lib/x86_64-linux-gnu/libc.so.6(clone+0x3f)
Dumping a stack trace of thread 'non-EPICS_140535820953344':
[    0x559e03ab28f3]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(epicsStackTrace+0x73)
[    0x559e03aa54c5]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(cantProceed+0xc5)
[    0x559e03aafce6]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(epicsThreadExitMain+0x56)
[    0x7fd15d189ebc]: /opt/libera/lib/libliberaistd.so.3.16(_ZN4istd6thread10thread_fncEPv+0x1c)
[    0x7fd15b8416db]: /lib/x86_64-linux-gnu/libpthread.so.0(start_thread+0xdb)
[    0x7fd15a5d6a3f]: /lib/x86_64-linux-gnu/libc.so.6(clone+0x3f)
Dumping a stack trace of thread 'non-EPICS_140536972199680':
[    0x559e03ab28f3]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(epicsStackTrace+0x73)
[    0x559e03aa54c5]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(cantProceed+0xc5)
[    0x559e03aafce6]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(epicsThreadExitMain+0x56)
[    0x7fd15d189ebc]: /opt/libera/lib/libliberaistd.so.3.16(_ZN4istd6thread10thread_fncEPv+0x1c)
[    0x7fd15b8416db]: /lib/x86_64-linux-gnu/libpthread.so.0(start_thread+0xdb)
[    0x7fd15a5d6a3f]: /lib/x86_64-linux-gnu/libc.so.6(clone+0x3f)
Dumping a stack trace of thread 'non-EPICS_140535794636544':
[    0x559e03ab28f3]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(epicsStackTrace+0x73)
[    0x559e03aa54c5]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(cantProceed+0xc5)
[    0x559e03aafce6]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(epicsThreadExitMain+0x56)
[    0x7fd15d189ebc]: /opt/libera/lib/libliberaistd.so.3.16(_ZN4istd6thread10thread_fncEPv+0x1c)
[    0x7fd15b8416db]: /lib/x86_64-linux-gnu/libpthread.so.0(start_thread+0xdb)
[    0x7fd15a5d6a3f]: /lib/x86_64-linux-gnu/libc.so.6(clone+0x3f)
Dumping a stack trace of thread 'non-EPICS_140536973252352':
[    0x559e03ab28f3]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(epicsStackTrace+0x73)
[    0x559e03aa54c5]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(cantProceed+0xc5)
[    0x559e03aafce6]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(epicsThreadExitMain+0x56)
[    0x7fd15d189ebc]: /opt/libera/lib/libliberaistd.so.3.16(_ZN4istd6thread10thread_fncEPv+0x1c)
[    0x7fd15b8416db]: /lib/x86_64-linux-gnu/libpthread.so.0(start_thread+0xdb)
[    0x7fd15a5d6a3f]: /lib/x86_64-linux-gnu/libc.so.6(clone+0x3f)
Dumping a stack trace of thread 'non-EPICS_140535825164032':
[    0x559e03ab28f3]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(epicsStackTrace+0x73)
[    0x559e03aa54c5]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(cantProceed+0xc5)
[    0x559e03aafce6]: /C2/iocs/afp/liberaLLRF/master/bin/linux-x86_64/liberaIOC(epicsThreadExitMain+0x56)
[    0x7fd15d189ebc]: /opt/libera/lib/libliberaistd.so.3.16(_ZN4istd6thread10thread_fncEPv+0x1c)
[    0x7fd15b8416db]: /lib/x86_64-linux-gnu/libpthread.so.0(start_thread+0xdb)
[    0x7fd15a5d6a3f]: /lib/x86_64-linux-gnu/libc.so.6(clone+0x3f)

Timers expire early

Generally, timers are supposed to sleep for at least the amount of time they were set for. However, the current EPICS timer implementation behaves differently:

# Testing timer accuracy
ok  2 - timerCount == nTimers
ok  3 - 0.486553 < 5.000000, delay = 1.000000 s, error = -0.004866 s (0.5 %)
ok  4 - 0.440644 < 5.000000, delay = 1.100000 s, error = -0.004847 s (0.4 %)
ok  5 - 0.404795 < 5.000000, delay = 1.200000 s, error = -0.004858 s (0.4 %)
ok  6 - 0.373543 < 5.000000, delay = 1.300000 s, error = -0.004856 s (0.4 %)
ok  7 - 0.346924 < 5.000000, delay = 1.400000 s, error = -0.004857 s (0.3 %)
ok  8 - 0.326921 < 5.000000, delay = 1.500000 s, error = -0.004904 s (0.3 %)
ok  9 - 0.303757 < 5.000000, delay = 1.600000 s, error = -0.004860 s (0.3 %)
ok 10 - 0.285826 < 5.000000, delay = 1.700000 s, error = -0.004859 s (0.3 %)
ok 11 - 0.270031 < 5.000000, delay = 1.800000 s, error = -0.004861 s (0.3 %)
ok 12 - 0.255543 < 5.000000, delay = 1.900000 s, error = -0.004855 s (0.3 %)
ok 13 - 0.242964 < 5.000000, delay = 2.000000 s, error = -0.004859 s (0.2 %)
ok 14 - 0.231398 < 5.000000, delay = 2.100000 s, error = -0.004859 s (0.2 %)
ok 15 - 0.220428 < 5.000000, delay = 2.200000 s, error = -0.004849 s (0.2 %)
ok 16 - 0.211106 < 5.000000, delay = 2.300000 s, error = -0.004855 s (0.2 %)
ok 17 - 0.202014 < 5.000000, delay = 2.400000 s, error = -0.004848 s (0.2 %)
ok 18 - 0.194164 < 5.000000, delay = 2.500000 s, error = -0.004854 s (0.2 %)
ok 19 - 0.186316 < 5.000000, delay = 2.600000 s, error = -0.004844 s (0.2 %)
ok 20 - 0.181187 < 5.000000, delay = 2.700000 s, error = -0.004892 s (0.2 %)
ok 21 - 0.173014 < 5.000000, delay = 2.800000 s, error = -0.004844 s (0.2 %)
ok 22 - 0.167593 < 5.000000, delay = 2.900000 s, error = -0.004860 s (0.2 %)
ok 23 - 0.163954 < 5.000000, delay = 3.000000 s, error = -0.004919 s (0.2 %)
ok 24 - 0.156422 < 5.000000, delay = 3.100000 s, error = -0.004849 s (0.2 %)
ok 25 - 0.152041 < 5.000000, delay = 3.200000 s, error = -0.004865 s (0.2 %)
ok 26 - 0.149199 < 5.000000, delay = 3.300000 s, error = -0.004924 s (0.1 %)
ok 27 - 0.142764 < 5.000000, delay = 3.400000 s, error = -0.004854 s (0.1 %)
# average timer delay error -4.863972 ms

Note how the timers are consistently expiring ~5 ms early (I ran this on a state-of-the-art Linux system). Turns out for some esoteric reason half a quantum is subtracted in timer::privateStart(). If other architectures require this adjustment it should probably only be applied to these architectures or alternatively the quantum should return 0 on modern Linux systems. The existing tests do not fail since they have a very generous tolerance of +/-5% (-0% +5% would probably be a better choice).

Related issues have been discussed in the past (see here and here) without any action taken. Considering the significant error and the popularity of Linux machines in the EPICS community I think this issue deserves to be addressed.

Windows target: vs2015 and later have working strtod()

The epicsParseDouble() routine calls epicsStrtod() which we introduced because the strtod() implementation on some OSs doesn't meet standards. This is implemented in libCom in an osi/os/ header osdStrtod.h, and our own implementation in misc/epicsStdlib.c which is defined if the header requests it. The epicsStdlibTest program checks the OS version of strtod() if we are currently using our own, so it's easy to tell when we can switch back.

The WIN32 version of osdStrtod.h has selected our own implementation for a while, but recent versions have been fixed:

This issue is a reminder for someone to fix osi/os/WIN32/osdStrtod.h so we use the OS version when compiling with vs2015 or later. This fix should probably be done on the 3.15 branch.

osiSockTest udpSockFanoutTest() failure on macOS when VPN running

This issue is minor and occurs on my laptop running macOS Catalina when I have the VPN connected:

woz$ cd modules/libcom/test/O.darwin-x86/
woz$ ./osiSockTest 
1..24
ok  1 - osiSockAttach
# udpSockTest()
ok  2 - epicsSocketCreate INET, DGRAM, 0
ok  3 - setsockopt BROADCAST := 1
ok  4 - getsockopt BROADCAST => 32
ok  5 - setsockopt BROADCAST := 0
ok  6 - getsockopt BROADCAST => 0
ok  7 - setsockopt MULTICAST_LOOP := 1
ok  8 - getsockopt MULTICAST_LOOP => 1
ok  9 - setsockopt MULTICAST_LOOP := 0
ok 10 - getsockopt MULTICAST_LOOP => 0
ok 11 - setsockopt IP_MULTICAST_TTL := 2
ok 12 - getsockopt IP_MULTICAST_TTL => 2
ok 13 - setsockopt IP_MULTICAST_TTL := 1
ok 14 - getsockopt IP_MULTICAST_TTL => 1
# udpSockFanoutBindTest()
# First test if epicsSocketEnableAddressUseForDatagramFanout() is necessary
ok 15 - bind() to port 49288
ok 16 - bind() to 49288 error -1, 48
# Now the real test
ok 17 - bind() to port 49288
ok 18 - bind() to port 49288
# udpSockFanoutTest()
# Interface 10.234.58.255:5064
# Not LO
# RX1 start
# RX2 start
# recvfrom error (35)
# RX1 end
# recvfrom error (35)
# RX2 end
# Result: RX1 0:0 RX2 0:0
# Interface 130.202.224.244:5064
# Not LO
# RX1 start
# RX1 success 2011178490
# RX2 start
# RX1 success 0
# RX1 success 1
# RX1 success 2
# RX1 success 3
# RX1 success 4
# RX1 end
# recvfrom error (35)
# RX2 end
# Result: RX1 1f:0 RX2 0:0
ok 19 - Found non-loopback interface
not ok 20 - Successes 0
# tcpSockReuseBindTest(0)
ok 21 - bind() to port 64874
ok 22 - bind() to 64874 error -1, 48
# tcpSockReuseBindTest(1)
# epicsSocketEnableAddressReuseDuringTimeWaitState
ok 23 - bind() to port 64875
ok 24 - bind() to 64875 error -1, 48

    Results
    =======
       Tests: 24 
      Passed:  23 = 95.83%
      Failed:   1 =  4.17%

The 10.234.58.* interface is my home WiFi, the second interface is my work VPN, which disappears when not connected.

The test passes if I disconnect from the VPN, or if I run it on my office workstation which doesn't have a VPN. Looking at older releases, it passed on 7.0.4 before udpSockFanoutTest() was added, failed on 7.0.4.1 which was the first release to add those checks and on 7.0.5.

if[n]eq RTEMS_VERSION in configure/os/CONFIG.Common.RTEMS-target files

E.g. in the file configure/os/CONFIG.Common.RTEMS-pc386 you can find the following:

ifneq ($(RTEMS_VERSION),5)
  $(info *** This target is not compatible with the configured RTEMS version.)
  $(info *** Build the RTEMS-pc386 (-qemu) target for RTEMS 4.x)
  $(error Can't continue)
endif

But when the file gets executed $RTEMS_VERSION is not defined.
How must/can this be done correctly? Of course I just copied this construct and now I had to realize that it does not work :-(
Danke Heinz

[PATCH] convertRelease ignores "undefine <macro>"

checkRelease.pl currently throws an error when the value for a macro has different values in two modules although the macro is undefined in a local release file.

Possible solution is

 src/tools/EPICS/Release.pm | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/tools/EPICS/Release.pm b/src/tools/EPICS/Release.pm
index 6ae0dbd9a..ebe1dab50 100644
--- a/src/tools/EPICS/Release.pm
+++ b/src/tools/EPICS/Release.pm
@@ -71,6 +71,13 @@ sub readRelease {
             $Rmacros->{$macro} = $val;
             next;
         }
+
+        # Handle "undefine <macro>" statements
+        my ($undefmacro) = m/^ \s* undefine \s* (\w+) /x;
+        if ($undefmacro ne '') {
+            delete $Rmacros->{$undefmacro} if exists $Rmacros->{$undefmacro}
+        }
+
         # Handle "include <path>" and "-include <path>" syntax
         my ($op, $path) = m/^ \s* (-? include) \s+ (.*)/x;
         $path = expandMacros($path, $Rmacros);
-- 
2.27.0

Conflict with libpcap on Centos-8

A build of the synApps MCA module R7-8 on Centos-8 died with this error, duplicate definitions of SOCKET and INVALID_SOCKET in libpcap-1.9.1 and osiSock.h:

make[4]: Entering directory '/home/anj/ioc-modules/build/MCA/7.8-C2-2+WEED-001/mcaApp/CanberraSrc/O.linux-x86_64'
/usr/bin/gcc  -D_GNU_SOURCE -D_DEFAULT_SOURCE         -DUSE_LIBNET -g `libnet-config --defines`    -D_X86_64_  -DUNIX  -Dlinux      -O3   -Wall     -DUSE_LIBNET -g `libnet-config --defines`   -mtune=generic      -m64 -fPIC -I. -I../O.Common -I. -I. -I.. -I../../../include/compiler/gcc -I../../../include/os/Linux -I../../../include   -I/home/anj/ioc-modules/build/CALC/3.7.2-C2-1+WEED-001/include   -I/home/anj/ioc-modules/build/SSCAN/2.11.2-C2-1+WEED-001/include   -I/home/anj/ioc-modules/build/SEQ/2.2.6-C2-2+WEED-001/include   -I/home/anj/ioc-modules/build/SCALER/4.0-C2-1+WEED-001/include   -I/home/anj/ioc-modules/build/BUSY/1.7.1-C2-1+WEED-001/include  -I/home/anj/ioc-modules/build/AUTOSAVE/5.10-C2-1+WEED-001/include/os/Linux -I/home/anj/ioc-modules/build/AUTOSAVE/5.10-C2-1+WEED-001/include   -I/home/anj/ioc-modules/build/ASYN/4.40-C2-2+WEED-001/include -I/home/anj/ioc-modules/build/BASE/7.0.4-C2-1+WEED-001/include/compiler/gcc -I/home/anj/ioc-modules/build/BASE/7.0.4-C2-1+WEED-001/include/os/Linux -I/home/anj/ioc-modules/build/BASE/7.0.4-C2-1+WEED-001/include        -c ../nmc_comm_subs_1.c
In file included from /usr/include/pcap/pcap.h:87,
                 from /usr/include/pcap.h:43,
                 from ../nmc_sys_defs.h:57,
                 from ../nmc_comm_subs_1.c:72:
/home/anj/ioc-modules/build/BASE/7.0.4-C2-1+WEED-001/include/os/Linux/osdSock.h:32:33: error: two or more data types in declaration specifiers
 typedef int                     SOCKET;
                                 ^~~~~~
In file included from /home/anj/ioc-modules/build/BASE/7.0.4-C2-1+WEED-001/include/osiSock.h:19,
                 from ../nmc_comm_subs_1.c:103:
/home/anj/ioc-modules/build/BASE/7.0.4-C2-1+WEED-001/include/os/Linux/osdSock.h:32:1: warning: useless type name in empty declaration
 typedef int                     SOCKET;
 ^~~~~~~
/home/anj/ioc-modules/build/BASE/7.0.4-C2-1+WEED-001/include/os/Linux/osdSock.h:33: warning: "INVALID_SOCKET" redefined
 #define INVALID_SOCKET          (-1)
 
In file included from /usr/include/pcap/pcap.h:87,
                 from /usr/include/pcap.h:43,
                 from ../nmc_sys_defs.h:57,
                 from ../nmc_comm_subs_1.c:72:
/usr/include/pcap/socket.h:89: note: this is the location of the previous definition
     #define INVALID_SOCKET -1

Mark Rivers has fixed this in MCA R7-9 with a #undef SOCKET immediately after the #include <pcap.h>, but this shows an issue with our osi/os/Linux/osiSock.h header which we should probably address. Those definitions are new since libpcap-1.5.3 as was shipped with RHEL-7.

Timestamp when monitoring non-VAL

#263 Fixes an issue where process() for waveformRecord called db_post_events() before TIME was updated by recGblGetTimeStampSimm(). So the posted update had the wrong timestamp.

At least aai and aao have the same code.

Lack of `fork()` safety

Documenting the current state of things. As it stands now, there are a number places where the Base APIs may not safely be used by a child process after a fork(). Adventurous users who investigate the safety of particular APIs are encouraged to note this, either in documentation, or on this issue.

Less adventurous users should assume that no Base API is safe to call/access from a child process after fork().

The general recommendation is to avoid usage of fork() when multiple threads exist in the parent process. A newly fork()d child process consists of only a single thread, and a copy of parent memory. So any other threads in the parent process effectively "disappear", leaving memory in an indeterminate state (eg. with a mutex locked). Further, some, but not all, parent file descriptors are inherited by the child. Unlike memory, these are not copies, so changes by the child may effect the parent.

Known safety issues in libCom

  1. The errlog worker thread
  2. The ipAddrToAsciiGlobal worker thread (emulation of asynchronous DNS)
  3. Free lists

Should use synchronous logging prior to IOC start

While some messages generated in dbLexRoutines.c are printed via fprintf, most are printed via various functions from errlog.h. So there is a mixture of synchronous and asynchronous logging, which results in messed-up output when parsing errors are encountered.

libca implementation doesn't follow one description in channel access protocol specification

I think that the fix will be made in the documentation, not the code.

This document states that

For compatibility, extended message form should only be used if payload size exceeds the pre-CA_V49 message size limit of 16368 bytes.

From this, we understand that caput, for example, needs to switch from standard header protocol to extended when the message is greater than 16368 bytes.

What is implemented, though, is that the switch from standard to extended happens when the message is greater than 0xffff:

if ( payloadSize < 0xffff && nElem < 0xffff ) {

Improve the CAS error message generated when an IOC gets port-scanned

I'm copying here the issue published in the codeathon ideas list: improve-the-cas-error-message-generated-when-an-ioc-gets-port-scanned

Read this tech-talk thread.

The code that needs changing is in camessage.c::camessage(). In the case described in tech-talk above, checking the condition msg.m_cmmd < NELEMENTS(tcpJumpTable) would have indicated that the TCP socket was not opened by a real CA client. There may be better ways to distinguish the first message received over TCP from a pre-3.12.0-beta1 client, but the IOC should attempt to detect non-CA clients and report them as such.

Error during build when using INSTALL_LOCATION

I've got a docker based build system that defines INSTALL_LOCATION but not EPICS_BASE. I assume 7ca25d3 was supposed to help prevent unhelpful errors further down in the build, but it has the side affect of making a previously working build now error for me.

libCom/calc optimization and alignment issues

I recently noticed this change in Diamond's RTEMS-4.11 work, which might explain some of the optimization issues we've been seeing with both calcPerform.c and postfix.c.

When the calls to memcpy() that copy double literals into/out of the byte-code stream are being optimized, maybe in some cases the optimizer doesn't realize that the byte-code end of the copy isn't guaranteed to be 8-byte aligned, although the other end is. A later commit removed this change to postfix.c with a comment that the -mstrict-align flag was sufficient to resolve their problem, so we definitely should add that to our RTEMS build flags — @hjunkes didn't you disable optimization for one or both of the libCom/calc files? We have also seen similar issues with the Microsoft optimizer though, which doesn't have -mstrict-align.

Diamond's solution in the above commit was to wrap the call to memcpy() which forced the optimizer to not make assumptions about the alignment. Is there a better, cross-platform way to do this?

waveformRecord missing PACT=true?

if (!pact && prec->pact)
return 0;
prec->udf = FALSE;
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);

Is waveformRecord missing a prec->pact = TRUE; before line 142? aaiRecord has one.

if (!pact && prec->pact)
return 0;
prec->pact = TRUE;
prec->udf = FALSE;
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);

Cross builds not setting SONAME

While shared libraries are always installed with the SHRLIB_VERSION suffix, this is only being used on a couple of host targets where the SONAME is actually being set.

$ readelf -d lib/linux-x86_64/libCom.so.3.19.0 |grep SONAME
 0x000000000000000e (SONAME)             Library soname: [libCom.so.3.19.0]
$ readelf -d lib/linux-aarch64/libCom.so.3.19.0 |grep SONAME

It looks like the -Wl,-h is only passed for certain host builds. Maybe this can move into configure/os/CONFIG.Common.linuxCommon?

$ git grep '\-Wl,-h'
configure/os/CONFIG.linux-x86.linux-x86:SHRLIB_LDFLAGS += -Wl,-h$@
configure/os/CONFIG.linux-x86.linux-x86:LOADABLE_SHRLIB_LDFLAGS += -Wl,-h$@
configure/os/CONFIG.solaris-sparc-gnu.solaris-sparc-gnu:SHRLIB_LDFLAGS += -Wl,-z,defs -Wl,-z,text -Wl,-h,$@
configure/os/CONFIG.solaris-sparc-gnu.solaris-sparc-gnu:LOADABLE_SHRLIB_LDFLAGS += -Wl,-z,text -Wl,-h,$@

Undefined timestamp on first camonitor update of NORD field

SLAC is seeing a problem when client apps are monitoring the NORD field of image waveforms.
If the client app is running and has a CA monitor pending, when the IOC boots
the monitor first reports UDF as the waveform has not yet processed.
Once it does, the first update doesn't get a timestamp.
A fresh caget or camonitor does see the timestamp.
% camonitor ioc:fillingwaveform.NORD
ioc:fillingwaveform.NORD 0 UDF INVALID
ioc:fillingwaveform.NORD 3 UDF INVALID
ioc:fillingwaveform.NORD 3 UDF INVALID
ioc:fillingwaveform.NORD 2022-05-12 14:18:00.721198 5
ioc:fillingwaveform.NORD 2022-05-12 14:18:00.721198 5

caget record.SSCN

I would like an improved response to this caget from a default-valued SSCN field:

woz$ caget bi.SSCN
CA.Client.Exception...............................................
    Warning: "Channel read request failed"
    Context: "op=0, channel=bi.SSCN, type=DBR_TIME_STRING, count=1, ctx="read failed""
    Source File: ../getCopy.cpp line 91
    Current Time: Thu Dec 16 2021 15:59:56.272797000
..................................................................
Read operation timed out: some PV data was not read.
bi.SSCN                 

On the IOC console output shown below, the first line comes from the above caget:

Illegal choice filename="(null)" line number=0PV: bi.SSCN error detected in routine: dbFastLinkConv(cvt_menu_st)
epics> dbgf bi.SSCN
Illegal choice filename="(null)" line number=0PV: bi.SSCN error detected in routine: dbFastLinkConv(cvt_menu_st)
DBF_STRING:         failed.   
epics> dbDumpField pdbbase bi SSCN
recordtype(bi) 
    SSCN
	         prompt: Sim. Mode Scan
	          extra: 
	      indRecordType: 66
	        special: 0 
	     field_type: DBF_MENU
	process_passive: 0
	       property: 0
	           base: 0
	    promptgroup: 90 - Simulate
	       interest: 1
	       as_level: 1
	        initial: 65535
		  menu: menuScan
	           size: 2
	         offset: 1022
Attribute: name RTYP value bi
Attribute: name VERS value none specified

There are several things in the above output that we could handle better (in addition to removing the filename and line number from those logged messages). The fundamental "why" of the error is that SSCN is a menu field with a default value that doesn't match any of the menuScan choices — a deliberate decision that I recommended to @ralphlange when he was working on the simulation enhancements and needed a "none of the above" choice value.

The IOC ought to behave better when it encounters that situation. Inside the IOC any out-of-range numeric puts to a menu field can cause this for almost any menu field. The behavior of a DBF_ENUM can be different from a DBF_MENU though since the IOC has separate converters for those two types.

Output from console interrupting typing

Is there a technical reason why output from the EPICS console has to interrupt what you type in the "epics>" prompt. This can make troubleshooting an IOC very frustrating. Why not isolate the "epics>" from the rest of the console like a linux or windows command line?

SingletonUntyped::pInstance warning

Folks,
compiling EPICS under Mingw gives a bunch of these warnings
(Any hints how to fix it ? I can prepare a PR)

g++ -D_MINGW -D__USE_MINGW_ANSI_STDIO -DBUILDING_libCa_API -O3 -Wall -m64 -DEPICS_BUILD_DLL -DEPICS_CALL_DLL -I. -I../O.Common -I. -I. -I.. -I../test -I../../../../../include/compiler/gcc -I../../../../../include/os/WIN32 -I../../../../../include -o netSubscription.obj -c ../netSubscription.cpp
In file included from ../localHostName.h:27,
from ../cac.h:32,
from ../netSubscription.cpp:30:
../../../../../include/epicsSingleton.h:164:15: warning: 'void* SingletonUntyped::pInstance() const' redeclared without dllimport attribute after being referenced with dll linkage
164 | inline void * SingletonUntyped :: pInstance () const
| ^~~~~~~~~~~~~~~~

Possible DLLSTUB Dependency issue

Mark Rivers reports that on Windows this reduced Makefile fragment

LIBRARY += xml2
xml2_SRCS += xml2.c
LIBRARY += nanohttp_stream
nanohttp_stream_SRCS += nanohttp_stream.c
nanohttp_stream_LIBS += xml2

can generate this error from parallel builds:

J:\epics\devel\areaDetector-3-11\ADSupport\supportApp\xml2Src>make -sj
make[1]: Circular xml2.lib <- nanohttp_stream.dll dependency dropped.

GNU's explanation for that error message is

Circular xxx <- yyy dependency dropped.
This means that make detected a loop in the dependency graph: after tracing the prerequisite yyy of target xxx, and its prerequisites, etc., one of them depended on xxx again.

On Windows when building with SHARED_LIBRARIES=YES the DLLSTUB .lib file is generated alongside a .dll file (SHRLIB).

It's reasonable to think that LIBRARY_template in configure/RULES_TARGET might need changing, but it's complicated and I don't have time to investigate at the moment.

RTEMS5 network issues/TODOs

A catalog of issues I'm seeing with an RTEMS5 build.

FHI defaults

These defaults shouldn't be hidden away in C code.

char rtemsInit_NTP_server_ip[16] = "10.0.5.1";
char bootp_server_name_init[128] = "[email protected]:/epics";
char bootp_boot_file_name_init[128] = "/epics/myExample/bin/RTEMS-beatnik/myExample.boot";
char bootp_cmdline_init[128] = "/epics/myExample/iocBoot/iocmyExample/st.cmd";

Timeouts

DHCP has a timeout, but NTP fetch does not. imo. this should be the other way around. This is problematic for me since with QEMU 3.1.0 at least, -net user the DHCP server doesn't seem to respond to option ntp_servers. (may be related by the next item)

DHCP option names

There may be an issue with option ntp_servers vs. options ntp-servers. cf. freebsd/sbin/dhclient/tables.c in the libbsd source, or /etc/dhcp/dhclient.conf.

"option ntp_servers\n"
"option rtems_cmdline\n"
"option tftp_server_name\n"
"option bootfile_name\n"

NIC emulation

-net nic,model=e1000 works for me... eventually.

-net nic,model=rtl8139 doesn't work for me. I see reason=CARRIER, but never reason=BOUND.

RTEMS and -ffunction-sections and -fdata-sections options

Code and Data Sections

RTEMS has supported options on most BSPs since RTEMS 5 and now 6:

  • -ffunction-sections
  • -fdata-sections

These options place each function and object file scoped variable in a separate .text and .data section. The linker only includes the referenced functions and variables from an object file in the executable due to the separate sections. The unreferenced functions and variables are garbage collected. This means a static global variable in a module that is not referenced will not be included.

EPICS uses the following construct in a few places:

/*
 * Register commands on application startup
 */
static int Registration() {
    iocshRegisterCommon();
    iocshRegister(&rrddFuncDef, rrddCallFunc);
    return 0;
}
static int done EPICS_UNUSED = Registration();

The unused variable done is not referenced so it will not be linked into the final application. As a result the automatic registration will not happen.


RTEMS Versions

  • RTEMS 5 exports these options in the BSP Makefile.inc compile flags. EPICS does not filter these flags so it is built with them.
  • RTEMS 6 only exports BSP machine ABI flags so these flags are not exported.
  • LibBSD requires these flags when building. We recommend applications using LibBSD provide these flags.
  • The linker options -Wl,--gc-sections must be used to enable garbage collection and removal of unused sections.

This means:

  • Building EPICS 7 with RTEMS 5 and the legacy networking stack for the mvme2700 BSP results in EPICS being built with these flags.
  • Building EPICS 7 with RTEMS 6 and LibBSD requires EPICS have these options in its compile flags.

Note: the register call happens early in the BSP start up and may work now but may fail depending on the calls to RTEMS or supporting libraries made. RTEMS 6 supports a SYSINIT approach for a structured and sequenced initialization.

Segfault when reading from compress record into aai record

Commit 542353a seems to have introduced a regression and segfault when reading from compress records into an aai record. Test db:

record(compress, "compress")
{
  field(ALG,  "Circular Buffer")
  field(INP,  "jaai PP")
  field(NSAM, "5")
  field(PINI, "YES")
}

record(aai, "caai")
{
  field(INP,  "42")
  field(NELM, "5")
  field(FTVL, "DOUBLE")
}

record(aai, "jaai")
{
  field(INP,  {const:[1,2,3,4,5]})
  field(NELM, "5")
  field(FTVL, "DOUBLE")
}

record(aai, "aai")
{
  field(INP,  "compress")
  field(NELM, "5")
  field(FTVL, "DOUBLE")
}

record(ao, "kill")
{
  field(FLNK, "aai")
}

dbpf kill 1 results in a segfault.

Changing if (dbLinkIsConstant(plink)) to if (plink->type == CONSTANT || plink->type == JSON_LINK) and moving dbInitLink(plink, DBF_INLINK); inside the if seems to fix the issue and correctly initializes the array:

diff --git a/modules/database/src/std/dev/devAaiSoft.c b/modules/database/src/std/dev/devAaiSoft.c
index 55975ba..99b46a7 100644
--- a/modules/database/src/std/dev/devAaiSoft.c
+++ b/modules/database/src/std/dev/devAaiSoft.c
@@ -47,13 +47,13 @@ static long init_record(dbCommon *pcommon)
     aaiRecord *prec = (aaiRecord *)pcommon;
     DBLINK *plink = &prec->inp;
 
-    /* This is pass 0, link hasn't been initialized yet */
-    dbInitLink(plink, DBF_INLINK);
-
-    if (dbLinkIsConstant(plink)) {
+    if (plink->type == CONSTANT || plink->type == JSON_LINK) {
         long nRequest = prec->nelm;
         long status;
 
+        /* This is pass 0, link hasn't been initialized yet */
+        dbInitLink(plink, DBF_INLINK);
+
         /* Allocate a buffer, record support hasn't done that yet */
         if (!prec->bptr) {
             prec->bptr = callocMustSucceed(nRequest, dbValueSize(prec->ftvl),

I don't know if it causes other problems though...

use CA Client in Xilinx MicroBlaze system

i want to use a CA Client in the Xilinx MicroBlaze System(mean i want to use some API to write a CA client), i don't know if i have to build a EPICS base for that system.(Actually, i don't know if there is any way to build a EPICS base for that system).

could you please give me some advice?

libCa doesn't properly handle errors from epicsTime_localtime()

This bug report comes from a machine which seems to have had problems with its timezone or its current time, such that the localtime_r() call in epicsTime_localtime() was returning an error. When libCa's ca_client_context::vSignal() method called current.strftime() to print the current time that resulted in a std::logic_error exception, which got caught by epicsThreadCallEntryPoint() in epicsThread.cpp for the "CAC-TCP-send" thread which found the original problem. At least the epicsThread::printLastChanceExceptionMessage() routine caught the repeated throw caused by trying to do the same thing, resulting in the <UKN DATE> string at the end of the logged output before it terminated the application.

The CA library should be protected against that kind of error, although I'm not sure where the best place will be to catch the internal exception. Other OS routine failures may cause similar issues.

Some `epicsThread*()` leak when called from a non-EPICS thread

Several of the epicsThread*() functions will allocate an epicsThreadOSD* the first time one is called from a thread not created with epicsThreadCreate*(). At present, this allocation is not free()'d automatically when the non-EPICS thread exits, causing a memory leak.

Status:

  • posix/osdThread.c - Leak observed. Fixed as of 2f8272d
  • RTEMS-score/osdThread.c - Believed to be ok
  • WIN32/osdThread.c - Candidate fix: #348
  • vxWorks/osdThread.c - Believed to be ok

Syntax Issue: Using epics base with legacy mongo-cxx driver

I am developing a service with mongo backend and v4. Naturally, I need to include certain features from base. As legacy mongo driver and epics base both have the concept of sockets, there is a small issue issue defining invalid sockets. We do it using the macros (sock.h, #define INVALID_SOCKET (-1)) and mongo driver uses const. Per @shengb suggested, sharing this here so someone can help us find a peaceful solution that does not require me to ship my own version of the base or the driver.

CA connections "stalled" after sleeping

I occasionally run IOCs on a raspberry pi board over wifi at my apartment. When I do, I occasionally notice long reconnect times after waking up my laptop in the morning. Last night I had left phoebus and a camonitor instance running. Recalling @anjohnson complaining of anomalous long reconnect times, after waiting for 1 minute I started wireshark recording instead of impatiently reloading/restarting as I otherwise would (I don't do mornings well).

I saw no searches being sent, but did see beacons from the IOCs (two, both on the pi board).

netstat on the laptop showed that both clients having active TCP connections, with non-zero Send-Q. netstat on the pi board showed no active connections (as expected).

$ netstat -tpn|grep 192.168.1.79
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0     32 192.168.1.68:33486      192.168.1.79:5064       ESTABLISHED 10604/./bin/linux-x 
tcp6       0     16 192.168.1.68:33504      192.168.1.79:5064       ESTABLISHED 3017/java           
tcp6       0     16 192.168.1.68:53762      192.168.1.79:37457      ESTABLISHED 3017/java

I did see a single ECHO request sent on two of the three connections (33486 and 33504), but no reply. (the IOCs had timed out long before).

After about 5 minutes I begin seeing TCP Retransmission requests on all three connections, repeating at ~30 second intervals.

(I'm surprised that none of this provoked a RST from the Linux IP stack the pi board)

Eventually, after ~15 minutes, something seemed to provoke both clients into reconnecting.

epicsAtomic TODOs

It looks like epicsAtomic operations for clang targets always use the (inefficient) interlocked fallback. A first task would be to investigate which clang versions provide the GCC __sync_* and/or __atomic_* builtins.

#ifndef epicsAtomicCD_h
#define epicsAtomicCD_h
#define EPICS_ATOMIC_CMPLR_NAME "CLANG"
#include "epicsAtomicOSD.h"
#endif /* epicsAtomicCD_h */

GCC >=4.7 adds the __atomic_* builtins. The __sync_* builtins are then described as "legacy", but not deprecated. It would be worth investigating if switching to __atomic_* would have any immediate benefit, or if we would only be getting ahead of an eventual deprecation.

EPICS_ATOMIC_INLINE int epicsAtomicIncrIntT ( int * pTarget )
{
return __sync_add_and_fetch ( pTarget, 1 );
}

DB link DBF_MENU to DBF_STRING conversions broken

From a bug report by Bayan Sobhani (Alex) I derived this test database:

record(ai, "ai") {}
record(stringin, "si") {
  field(INP, "ai.SEVR")
}

This shows the break on the 7.0 branch:

woz$ ./base-7.0/bin/darwin-x86/softIoc -d ~/db/test.db
Starting iocInit
############################################################################
## EPICS R7.0.5.1-DEV
## Rev. R7.0.5-264-g7ca25d3c888c56844877-dirty
############################################################################
iocRun: All initialization complete
epics> dbpf si.PROC 1
missing record support entry table Record Support Routine (get_enum_str) Record Type ai PV ai.SEVR  dbGetField

DBF_UCHAR:          1 = 0x1   
epics>

The database works properly with 3.15.9, 7.0.2 and 7.0.4.

SEVR is a DBF_MENU field, so the code shouldn't be trying to call the RSET::get_enum_str() routine for it anyway.

Initial alarm STAT and SEVR of Base record types

The bo and mbbo record types don't raise a STATE_ALARM in their init_record() routines even if the *SV field corresponding to the current state is set. It is often undesirable to set PINI on output records (which would also fix this), to avoid writing to hardware unnecessarily.

Other record types might have similar issues with their initial states.

woz$ cat do-init-sev.db 
record(bo, bo) {
  field(ZSV, MINOR)
  field(ZNAM, Zero)
  field(VAL, 0)
}

record(mbbo, mbbo) {
  field(ZRSV, MINOR)
  field(ZRST, Zero)
  field(VAL, 0)
}
woz$ caget -a bo mbbo
bo                             <undefined> Zero UDF NO_ALARM
mbbo                           <undefined> Zero UDF NO_ALARM

After processing both records:

woz$ caget -a bo mbbo
bo                             2021-06-01 12:40:27.046965 Zero STATE MINOR
mbbo                           2021-06-01 12:40:41.207460 Zero STATE MINOR

Noticed while investigating epics-modules/asyn#136.

These kinds of changes to record types should probably be discussed and agreed (on core-talk or tech-talk) before making them though.

Avoid intentional memory leak in `epicsEnvSet()`

epicsEnvSet() has different implementations, some of which use setenv(), and some putenv(). Those using putenv() currently leak on each call since the buffer passed to putenv() may be referenced by the libc for some indeterminate time. Currently this is the case for: default, WIN32, and vxWorks. The others use setenv()

The default impl (used by eg. Linux) could probably be switched to use setenv() at this point. Windows has _putenv_s which seems to work like setenv(). @anjohnson says that with at least recent vxWorks (>=6.8), putenv() is making a copy of the provided buffer, which we could then free.

$ git ls-files|grep osdEnv
modules/libcom/src/osi/os/Darwin/osdEnv.c
modules/libcom/src/osi/os/RTEMS/osdEnv.c
modules/libcom/src/osi/os/WIN32/osdEnv.c
modules/libcom/src/osi/os/default/osdEnv.c
modules/libcom/src/osi/os/iOS/osdEnv.c
modules/libcom/src/osi/os/solaris/osdEnv.c
modules/libcom/src/osi/os/vxWorks/osdEnv.c

UB fork() warnings from legal code

#include <unistd.h>

int main()
{
    return fork();
}

Compiling and linking the program above against libCom causes it to trigger the warning added in PR #214 on MacOS. I suspect Linux will behave the same but I haven't actually tried it. Adding calls to epicsThreadShowAll() demonstrate that no EPICS threads are running immediately before or after the fork, so I think the current check is too simplistic. I had assumed it would only warn if a thread is actually started before fork() is called.

Passing -s to the ca-nameserver or ca-gateway (which tells them to detach from their parent session) causes them to generate this warning incorrectly. IMHO a server process which double-forks to disconnect and become a session leader before it makes any EPICS calls should not be triggering the warning.

Posix implementation of epicsEvent is unsuitable for RTEMS-posix targets

The code in libCom/osi/os/posix/osdEvent.c was written for workstation OSs that don't support true ISRs. The struct epicsEventOSD in that file which implements the epicsEvent object contains both a pthread_mutex_t and a pthread_cond_t. Unfortunately neither of these can be used in ISR context on an RTEMS-posix target. The epicsEventTrigger() routine must be callable from ISR context when the target supports them.

Discovered by @hjunkes and @mdavidsaver.

size of array error

referenced file:
src/libCom/test/epicsExceptionTest.cpp
epics (stable) version 3.15.4
compiler: gcc, cpp, g++ version 6.1.1

/epicsExceptionTest.cpp: In function ‘void epicsExceptionTestPrivate()’:
../epicsExceptionTest.cpp:61:49: error: size of array is too large
char * p = new char [unsuccessfulNewSize];
^
../epicsExceptionTest.cpp:74:38: error: size of array is too large
char [unsuccessfulNewSize];
^

Constant `INP*` to aSub

cf. https://epics.anl.gov/tech-talk/2022/msg01154.php

record(aSub,"$(user):aSubExample")
{
   field(INAM,"myAsubInit")
   field(SNAM,"myAsubProcess")
   field(FTA,"DOUBLE")
   field(NOA,"10")
   field(INPA,"$(user):compressExample CPP")
   field(FTB,"DOUBLE")
   field(NOB,"1")
   field(INPB,"123")
}

Stepping through aSubRecord.c, it looks like init_record() does the right thing, and leaves B=123 and NEB=1.

dbLoadLinkArray(plink, dbr, (&prec->a)[i], &n);
if (n > 0)
(&prec->nea)[i] = n;

However, later in fetch_values(), there is no dbLinkIsConstant() test, so the call to dbGetLink() goes to dbConstGetValue() where NEB is set to zero.

long nRequest = (&prec->noa)[i];
status = dbGetLink(&(&prec->inpa)[i], (&prec->fta)[i], (&prec->a)[i], 0,
&nRequest);
if (status)
return status;
(&prec->nea)[i] = nRequest;

if (pnRequest)
*pnRequest = 0;

Apply some GCC attributes

GCC (and usually clang) has a number of __attribute__(())s which it might be useful to (conditionally) apply to some Base functions to facilitate static analysis/optimization by the compiler.

https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes

eg. alloc_size(...) to provide size hints, or malloc(deallocator, ptr-index) to match alloc and dealloc functions, could be added to various memory allocation functions. eg.

__attribute__((malloc(freeListFree,2)))
void* freeListMalloc(void *pvt)

__attribute__((alloc_size(1,2),malloc(free,1),returns_nonnull))
void* callocMustSucceed(size_t count, size_t size,  const char *errorMessage);

Some of the simpler, or more common, might be abstracted through compilerDependencies.h (eg. deprecated/error/warning or warn_unused_result). Though the more specialized/complicated probably have to be special cases.

Complications include identifying supported GCC versions ranges. (although GCC usually treats unknown attributes as a warning).

/src/tools/makeRPath.py shebang does not specify python version

The 'makeRPath' python script in /src/tools uses a #!/usr/bin/env python shebang. This results in using the default python2 on Debian systems, which is deprecated with the release of Debian 11 (bullseye). Does this need to be run on python 2 (in which case the shebang should be changed to #!/usr/bin/env python2 or can python3 be specified?

[⁨libcom⁩/⁨osi] osdTimeGetCurrent doesn't work for subprocess on macos

Hello,

I am having some issues using pyepics on macos, when using CAProcess to create a subprocess. I managed to track the issue down to libcom/osi in base.

In macos, calling osdTimeGetCurrent() from a subprocess gives wrong results if osdTimeGetCurrent() was called beforehand.
The reason is that in order to use clock_get_time(), one first need to call host_get_clock_service() to get a port to the host clock. This is done in osi/os/Darwin/osdTime.cpp in the static function timeRegister(), but the subprocess would require a different port.

I've seen that the high-resolution time provider was added in 2013 by @anjohnson:
738b8ca

The previous implementation using gettimeofday() works fine, although with a 1us resolution. The simplest solution would be to revert to that implementation, if the lower resolution is acceptable.

This snippet below can be used to prove the issue:

#include <stdlib.h>
#include <stdio.h>
#include <mach/mach.h>
#include <mach/clock.h>
#include <unistd.h>

int main()
{
    clock_serv_t host_clock;

    host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &host_clock);

    mach_timespec_t mts, mts2;

    clock_get_time(host_clock, &mts);

    printf("s=%d\tns=%d\n", mts.tv_sec, mts.tv_nsec);

    pid_t pid = fork();
    clock_get_time(host_clock, &mts2);

    if (pid == 0)
    {
        printf("Child:\ns=%d\tns=%d\n", mts2.tv_sec, mts2.tv_nsec);
    }
    else
    {
        printf("Parent:\ns=%d\tns=%d\n", mts2.tv_sec, mts2.tv_nsec);
    }

    if (pid == 0)
    {
        host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &host_clock);
        clock_get_time(host_clock, &mts2);

        printf("Child after getting new clock service port:\ns=%d\tns=%d\n", mts2.tv_sec, mts2.tv_nsec);
    }

    return 0;
}

errSymbolAdd() only works if called before errlogInit()

Support modules can (and do, e.g. see here) add error symbols to the error symbol table by calling errSymbolAdd(), but must do so before errlogInitPvt() has called errSymBld(). If called too late the symbols are not added to the hash table so don't get found when they are looked up for printing (if I've understood the code properly).

The implementation needs correcting so error symbols can be added at any time and get inserted into the hash table as well, but there are currently no locks protecting the data structures in errSymLib.c so they need adding as well, preferably in a way that doesn't require a separate lock/unlock for each symbol that gets added by errSymBld() though.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.