Closed mdavidsaver closed 5 years ago
This has been confirmed as an issue on RTEMS and vxWorks targets with hard-float. The fault is in testStructure()
of testSerialization.cpp.
# Testing structure...
ok 160 - factory.get()!=NULL
# Simple structure serialization
... crash
Candidate fix a51b308cc87e10cbe77c8057d3b96130697fa7a5
CA has long used a set of inline C++ templates defined in libCom's osiWireFormat.h and osdWireFormat.h to do unaligned data copying and byte swapping, which Jeff wrote to be optimizable by older compilers. Other than their obscure names is there any reason we couldn't use these instead of rewriting yet more of libCom inside pvDataCPP? I guess the absence of 64-bit integer support is a good one (I have a fix for that which I can commit to 3.15 or 3.16) and I know you didn't write the original code in byteBuffer.h, but it would be nice to be able to reduce this kind of duplication in the future.
Please consider initial version (before refactorisation) of byteBuffer.h that handled unaligned/aligned access. I remember testing it on different platforms and comparing performance using different methods. For Intels (x86, x64, etc) it is the best not to handle alignment by yourself, CPU does it for you. For older CPUs (ppc, etc.) you must.
In addition use memcpy for large blocks of data to allow vectorization.
@msekoranja FYI, it depends on your target. It worked fine on RTEMS targets with soft-float (eg. mvme3100). Also, my refactoring wasn't a functional change due to:
#define UNALIGNED_ACCESS true
cf. c762d94f7af1aed0fc49ef113adb5ecadcdf8467
@anjohnson I had forgotten about osiWireFormat.h. I'll look at it.
See branch wire-format-64 on https://git.launchpad.net/~anj/epics-base/+git/base-3.16 for the Int64 additions to os*WireFormat.h.
wrt. osiWireFormat.h the first thing I notice is that these ops combines unaligned access with byte order swap. In CA world this is always host to/from big endian (a la. hton*()). PVA needs conditional byte order swapping.
That would be a pretty good reason it can't be used then — sorry!
np. It was an interesting reminder of how nice it is that we only have to worry about 2's complement integers and ieee floating point.
oh, I also discovered 'class comBuf' (src/ca/client/comBuf.h) which seems like the conceptual equivalent of ByteBuffer, with a dose of codec.h thrown in as well. So much of libca only makes sense to me after I see/write another solution to the same problem.
FYI I'm seeing a new compiler warning from byteBuffer.h that probably came from this commit:
../../src/misc/pv/byteBuffer.h: In instantiation of ‘void epics::pvData::ByteBuffer::getArray(T*, std::size_t) [with T = double; std::size_t = long unsigned int]’:
../../src/factory/PVDataCreateFactory.cpp:257:9: required from ‘void epics::pvData::PVValueArray<T>::deserialize(epics::pvData::ByteBuffer*, epics::pvData::DeserializableControl*) [with T = double]’
../../src/factory/PVDataCreateFactory.cpp:660:1: required from here
../../src/misc/pv/byteBuffer.h:825:18: warning: unused variable ‘start’ [-Wunused-variable]
const T* start = (T*)_position;
^
I just found another useful page on our Jenkins, I got this link from the compiler warnings page for pvData; if you visit it you'll see the line with the warning in orange, and hovering over it shows the warning message.
This warning is innocuous, and also fixed by b4cd026fe5c361dbf15b71cfab87b4dac98528c8
The candidate fix https://github.com/epics-base/pvDataCPP/commit/a51b308cc87e10cbe77c8057d3b96130697fa7a5 did resolve this issue.
Released with Base 7.0.2
Till Straumann reports https://bugs.launchpad.net/epics-base/+bug/1754787