epics-base/p4p

Wrong representation of unsigned types on the client

Closed this issue · 7 comments

Hi Michael,

While doing some tests with unsigned types, I discovered that the client is not representing the values for the higher half of the range for unsigned types correctly. The server part seems to be working well with unsigned types.

For example, this PV:

$ pvget TYPES_TEST:PV:USHORT
TYPES_TEST:PV:USHORT 2023-03-20 09:09:49.177  48303 

Gets this result using p4p-4.1.2:

ctxt.get('TYPES_TEST:PV:USHORT')
18446744073709534383

It seems the conversion is done in 2 steps:

  1. 48303 is represented as a signed short: 2**16 - 1 - 48303 = -17232
  2. The previous value is converted to unsigned long: 2**64 - 1 - 17232 = 18446744073709534383

This seems to be a regression introduced when upgrading p4p to use pvxs, because I don't see the issue using v3.5.

I forgot to mention, this issue does not affect arrays, only scalar PVs.

For completeness, what is serving TYPES_TEST:PV:USHORT?

... and what does pvinfo TYPES_TEST:PV:USHORT show?

That PV came from a rather large structure, so I prepared a minimal reproducible example using p4p:

from p4p.nt import NTScalar
from p4p.server import Server
from p4p.server.thread import SharedPV

pv = SharedPV(nt=NTScalar('B'),
              initial=2**7)
@pv.put
def handle(pv, op):
    pv.post(op.value())
    op.done()

Server.forever(providers=[{
    'demo:pv:ubyte':pv,
}])

Using pvget:

$ pvget demo:pv:ubyte
demo:pv:ubyte <undefined>              128 

Using p4p-4.1.2

>>> from p4p.client.thread import Context
>>> ctxt = Context()
>>> ctxt.get('demo:pv:ubyte')
18446744073709551488

And pvinfo output:

$ pvinfo demo:pv:ubyte
demo:pv:ubyte
Server: X.X.X.X:5075
Type:
    epics:nt/NTScalar:1.0
        ubyte value
        alarm_t alarm
            int severity
            int status
            string message
        time_t timeStamp
            long secondsPastEpoch
            int nanoseconds
            int userTag

I think this issue is fixed by epics-base/pvxs@7d16ab3. Can you confirm?

Yes, that fixes the issue. I tested all unsigned types successfully.
Thanks for fixing it so quickly!

Fix released as pvxslibs==1.1.3.