diff --git a/configure/CONFIG_SITE b/configure/CONFIG_SITE index 6c7f08239..e638ae2cd 100644 --- a/configure/CONFIG_SITE +++ b/configure/CONFIG_SITE @@ -118,6 +118,13 @@ CROSS_COMPILER_TARGET_ARCHS= # configure/os/CONFIG_SITE..Common files instead. CROSS_COMPILER_HOST_ARCHS= +# The 'make runtests' and 'make tapfiles' build targets normally only run +# self-tests for the EPICS_HOST_ARCH architecture. If the host can execute +# the self-test programs for any other cross-built architectures such as +# a -debug architecture, those architectures can be named here. +# +CROSS_COMPILER_RUNTEST_ARCHS= + # Build shared libraries (DLLs on Windows). # Must be either YES or NO. Definitions in the target-specific # os/CONFIG.Common. and os/CONFIG_SITE.Common. files may diff --git a/configure/RULES_BUILD b/configure/RULES_BUILD index 026246ee6..310744605 100644 --- a/configure/RULES_BUILD +++ b/configure/RULES_BUILD @@ -325,7 +325,9 @@ $(MODNAME): %$(MODEXT): %$(EXE) # Automated testing runtests: $(TESTSCRIPTS) +ifneq (,$(findstring $(T_A),$(EPICS_HOST_ARCH) $(CROSS_COMPILER_RUNTEST_ARCHS))) -$(PERL) -MTest::Harness -e 'runtests @ARGV if @ARGV;' $^ +endif testspec: $(TESTSCRIPTS) @$(RM) $@ @@ -339,7 +341,9 @@ tapfiles: $(TESTSCRIPTS) $(TAPFILES) # A .tap file is the output from running the associated test script %.tap: %.t +ifneq (,$(findstring $(T_A),$(EPICS_HOST_ARCH) $(CROSS_COMPILER_RUNTEST_ARCHS))) -$(PERL) $< -tap > $@ +endif # If there's a perl test script (.plt) available, use it %.t: ../%.plt diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 4ddb9bec3..a24ac1d25 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -109,6 +109,53 @@ dbQuietMacroWarnings=1 VxWorks

Changes pulled from the 3.14 branch since 3.15.3

+

New CONFIG_SITE variable for running self-tests

+ +

The 'make runtests' and 'make tapfiles' build targets normally only run the +self-tests for the main EPICS_HOST_ARCH architecture. If the host is +able to execute self-test programs for other target architectures that are being +built by the host, such as when building a -debug version of the host +architecture for example, the names of those other architectures can be added to +the new CROSS_COMPILER_RUNTEST_ARCHS variable in either the +configure/CONFIG_SITE file or in an appropriate +configure/os/CONFIG_SITE.<host>.Common file to have the test +programs for those targets be run as well.

+ +

Additional RELEASE file checks

+ +

An additional check has been added at build-time for the contents of the +configure/RELEASE file(s), which will mostly only affect users of the Debian +EPICS packages published by NSLS-2. Support modules may share an install path, +but all such modules must be listed adjacent to each other in any RELEASE files +that point to them. For example the following will fail the new checks:

+ +
+AUTOSAVE = /usr/lib/epics
+ASYN = /home/mdavidsaver/asyn
+EPICS_BASE = /usr/lib/epics
+
+ +

giving the compile-time error

+ +
+This application's RELEASE file(s) define
+	EPICS_BASE = /usr/lib/epics
+after but not adjacent to
+	AUTOSAVE = /usr/lib/epics
+Module definitions that share paths must be grouped together.
+Either remove a definition, or move it to a line immediately
+above or below the other(s).
+Any non-module definitions belong in configure/CONFIG_SITE.
+
+ + +

In many cases such as the one above the order of the AUTOSAVE and +ASYN lines can be swapped to let the checks pass, but if the +AUTOSAVE module depended on ASYN and hence had to appear +before it in the list this error indicates that AUTOSAVE should also be +built in its own private area; a shared copy would likely be incompatible with +the version of ASYN built in the home directory.

+

String field buffer overflows

Two buffer overflow bugs that can crash the IOC have been fixed, caused by diff --git a/src/ca/client/perl/Makefile b/src/ca/client/perl/Makefile index bac6e347a..fb0fc96ff 100644 --- a/src/ca/client/perl/Makefile +++ b/src/ca/client/perl/Makefile @@ -20,10 +20,19 @@ ifeq ($(OS_CLASS),Darwin) LOADABLE_SHRLIB_SUFFIX = .$(shell $(PERL) ../perlConfig.pl dlext) endif -PERL_VERSION = $(shell $(PERL) ../perlConfig.pl version) -PERL_ARCHNAME = $(shell $(PERL) ../perlConfig.pl archname) -PERL_ARCHPATH = $(PERL_VERSION)/$(PERL_ARCHNAME) +ifdef T_A + PERL_VERSION = $(shell $(PERL) ../perlConfig.pl version) + PERL_ARCHNAME = $(shell $(PERL) ../perlConfig.pl archname) + PERL_ARCHPATH := $(PERL_VERSION)/$(PERL_ARCHNAME) + EXTUTILS := $(shell $(PERL) ../perlConfig.pl privlib)/ExtUtils + PERLBIN := $(shell $(PERL) ../perlConfig.pl bin) + XSUBPP := $(firstword $(wildcard $(PERLBIN)/xsubpp $(EXTUTILS)/xsubpp)) + +ifeq ($(strip $(XSUBPP)),) + $(warning Perl's xsubpp program was not found.) + $(warning The Perl CA module will not be built.) +else ifeq ($(T_A),$(EPICS_HOST_ARCH)) # No cross-builds (wrong Perl!) ifeq ($(findstring $(OS_CLASS),WIN32 cygwin32),) # Doesn't build on WIN32 LOADABLE_LIBRARY_HOST = Cap5 @@ -41,6 +50,8 @@ ifeq ($(findstring $(OS_CLASS),WIN32 cygwin32),) # Doesn't build on WIN32 HTMLS = CA.html endif endif +endif +endif Cap5_SRCS = Cap5.xs Cap5_LIBS = ca Com @@ -52,10 +63,6 @@ CLEANS += Cap5.c pod2htmd.tmp pod2htmi.tmp include $(TOP)/configure/RULES ifdef T_A - EXTUTILS = $(shell $(PERL) ../perlConfig.pl privlib)/ExtUtils - PERLBIN = $(shell $(PERL) ../perlConfig.pl bin) - XSUBPP = $(firstword $(wildcard $(PERLBIN)/xsubpp $(EXTUTILS)/xsubpp)) - %.c: ../%.xs $(RM) $@ $@_new $(PERL) $(XSUBPP) -typemap $(EXTUTILS)/typemap $< > $@_new && $(MV) $@_new $@ diff --git a/src/ioc/db/db_field_log.h b/src/ioc/db/db_field_log.h index 93a1fefdb..c39c390b1 100644 --- a/src/ioc/db/db_field_log.h +++ b/src/ioc/db/db_field_log.h @@ -19,7 +19,8 @@ #ifndef INCLdb_field_logh #define INCLdb_field_logh -#include "epicsTime.h" +#include +#include #ifdef __cplusplus extern "C" { @@ -32,18 +33,20 @@ extern "C" { * priority task pending on the event queue wakes up). Strings would slow down * events for more reasonable size values. DB fields of native type string * will most likely change infrequently. - * + * + * Strings can be added to the set of types for which updates will be queued + * by defining the macro DB_EVENT_LOG_STRINGS. The code in db_add_event() + * will adjust automatically, it just compares field sizes. */ union native_value { - short dbf_int; - short dbf_short; - float dbf_float; - short dbf_enum; - char dbf_char; - long dbf_long; - double dbf_double; + epicsInt8 dbf_char; + epicsInt16 dbf_short; + epicsEnum16 dbf_enum; + epicsInt32 dbf_long; + epicsFloat32 dbf_float; + epicsFloat64 dbf_double; #ifdef DB_EVENT_LOG_STRINGS - char dbf_string[MAX_STRING_SIZE]; + char dbf_string[MAX_STRING_SIZE]; #endif }; diff --git a/src/ioc/rsrv/camessage.c b/src/ioc/rsrv/camessage.c index b992b46eb..b5c265ca6 100644 --- a/src/ioc/rsrv/camessage.c +++ b/src/ioc/rsrv/camessage.c @@ -1112,7 +1112,7 @@ unsigned cid * casAccessRightsCB() * * If access right state changes then inform the client. - * + * asLock is held */ static void casAccessRightsCB(ASCLIENTPVT ascpvt, asClientStatus type) { @@ -1568,6 +1568,9 @@ static void sendAllUpdateAS ( struct client *client ) else if ( pciu->state == rsrvCS_inServiceUpdatePendAR ) { access_rights_reply ( pciu ); } + else if ( pciu->state == rsrvCS_shutdown ) { + /* no-op */ + } else { errlogPrintf ( "%s at %d: corrupt channel state detected durring AR update\n", @@ -2047,10 +2050,15 @@ static int clear_channel_reply ( caHdrLargeArray *mp, if ( pciu->state == rsrvCS_inService || pciu->state == rsrvCS_pendConnectResp ) { ellDelete ( &client->chanList, &pciu->node ); + pciu->state = rsrvCS_shutdown; } else if ( pciu->state == rsrvCS_inServiceUpdatePendAR || pciu->state == rsrvCS_pendConnectRespUpdatePendAR ) { ellDelete ( &client->chanPendingUpdateARList, &pciu->node ); + pciu->state = rsrvCS_shutdown; + } + else if ( pciu->state == rsrvCS_shutdown ) { + /* no-op */ } else { epicsMutexUnlock( client->chanListLock ); diff --git a/src/ioc/rsrv/caservertask.c b/src/ioc/rsrv/caservertask.c index 310cabb29..cbc9233e8 100644 --- a/src/ioc/rsrv/caservertask.c +++ b/src/ioc/rsrv/caservertask.c @@ -1134,6 +1134,7 @@ static void destroyAllChannels ( epicsMutexMustLock ( client->chanListLock ); pciu = (struct channel_in_use *) ellGet ( pList ); + if(pciu) pciu->state = rsrvCS_shutdown; epicsMutexUnlock ( client->chanListLock ); if ( ! pciu ) { diff --git a/src/ioc/rsrv/server.h b/src/ioc/rsrv/server.h index a1094c2eb..d2a1cf3f4 100644 --- a/src/ioc/rsrv/server.h +++ b/src/ioc/rsrv/server.h @@ -99,12 +99,25 @@ typedef struct client { char disconnect; /* disconnect detected */ } client; +/* Channel state shows which struct client list a + * channel_in_us::node is in. + * + * client::chanList + * rsrvCS_pendConnectResp, rsrvCS_inService + * client::chanPendingUpdateARList + * rsrvCS_pendConnectRespUpdatePendAR, rsrvCS_inServiceUpdatePendAR + * Not in any list + * rsrvCS_shutdown + * + * rsrvCS_invalid is not used + */ enum rsrvChanState { rsrvCS_invalid, rsrvCS_pendConnectResp, rsrvCS_inService, rsrvCS_pendConnectRespUpdatePendAR, - rsrvCS_inServiceUpdatePendAR + rsrvCS_inServiceUpdatePendAR, + rsrvCS_shutdown }; /* diff --git a/src/tools/convertRelease.pl b/src/tools/convertRelease.pl index 70f38ed57..eda7c2a37 100644 --- a/src/tools/convertRelease.pl +++ b/src/tools/convertRelease.pl @@ -215,7 +215,7 @@ sub checkRelease { delete $macros{RULES}; delete $macros{TOP}; delete $macros{TEMPLATE_TOP}; - + while (my ($app, $path) = each %macros) { my %check = (TOP => $path); my @order = (); @@ -238,7 +238,35 @@ sub checkRelease { } } } - print "\n" if ($status); + + my @modules = @apps; + my $app = shift @modules; + my $latest = AbsPath($macros{$app}); + my %paths = ($latest => $app); + foreach $app (@modules) { + my $path = AbsPath($macros{$app}); + if ($path ne $latest && exists $paths{$path}) { + my $prev = $paths{$path}; + print "\n" unless ($status); + print "This application's RELEASE file(s) define\n"; + print "\t$app = $macros{$app}\n"; + print "after but not adjacent to\n\t$prev = $macros{$prev}\n"; + print "both of which resolve to $path\n" + if $path ne $macros{$app} || $path ne $macros{$prev}; + $status = 2; + } + $paths{$path} = $app; + $latest = $path; + } + if ($status == 2) { + print "Module definitions that share paths must be grouped together.\n"; + print "Either remove a definition, or move it to a line immediately\n"; + print "above or below the other(s).\n"; + print "Any non-module definitions belong in configure/CONFIG_SITE.\n"; + $status = 1; + } + + print "\n" if $status; exit $status; }