For long string buffers, we currently write a null terminator one byte
past the end of the buffer. This can be seen with a record of the type
```
record(aai, foo) {
field(NELM, 1)
field(FTVL, CHAR)
field(INP, {const: "foo"})
}
```
where the buffer is only of size 1, but then we write at index 1 (aka
past the end of the buffer).
Co-authored-by: Lucas A. M. Magalhães <lucmaga@gmail.com>
The handling of N-to-M array compression was broken with the addition
of the partial buffer option, which broke the bounds check that was
being used.
Note that this also makes the partial buffer option more consistent;
if, for example, you have
```
record(compress, foo) {
field(ALG, "N to 1 Average")
field(INP, "bar NPP")
field(NSAM, 2)
field(N, 2)
field(PBUF, YES)
}
```
(with `bar` having, e.g. length 3), then this will now behave as
expected on both of the samples.
The watchdog tasks are allocated, but not consistently removed. In
general this doesn't matter: they run in threads that will only
end when the process actually quits. For consistency and for the
purpose of future-proofing, I think there is value in having the
cleanup added in each case.
The call to setThreadName() is moved to avoid a race condition that
can happen with very short lived processes. If the process terminates
very quickly e.g. is a google test runner or the msi.exe command
called from a Makefile during a build, then very occasionally a
crash can occur during process termination if setThreadName() when called
from the newly created thread. This looks to be becauae the DLL it is
trying to call gets unloaded between it getting a handle to the DLL
and making the call. Moving the setThreadName() call to the creating
thread avoids this problem. The issue was only ever seen with statically
linked epics executables, I am unsure if the way a DLL based epics
program unloads might avoid this, or just make it less likely but
still possible. As mentioned above, the issue will only ever occur
to threads that are created during process termination and so would
not affect running IOCs