Bruce Schuchardt created GEODE-7219:
---------------------------------------

             Summary: BufferUnderflowException in PutReplyMessage 
deserialization
                 Key: GEODE-7219
                 URL: https://issues.apache.org/jira/browse/GEODE-7219
             Project: Geode
          Issue Type: Bug
          Components: regions
            Reporter: Bruce Schuchardt


I ran into this exception in three different regression tests and see history 
of it happening in other people's tests.  I think it's due to 
VersionTag.toData() making serialization decisions at the same time some other 
thread is modifying the version tag.

{noformat}
[fatal 2019/09/18 00:47:52.835 PDT <P2P message reader for 
rs-Awesome-549-1146a0i3large-hydra-client-10(bridgegemfire1_host1_12399:12399)<ec><v1>:41001
 unshared ordered uid=452 dom #2 port=46062> tid=0xdd] Error deserializing 
message
java.nio.BufferUnderflowException
        at java.nio.Buffer.nextGetIndex(Buffer.java:500)
        at java.nio.DirectByteBuffer.get(DirectByteBuffer.java:249)
        at 
org.apache.geode.internal.tcp.ByteBufferInputStream$ByteBufferByteSource.get(ByteBufferInputStream.java:206)
        at 
org.apache.geode.internal.tcp.ByteBufferInputStream.readByte(ByteBufferInputStream.java:892)
        at 
org.apache.geode.internal.serialization.StaticSerialization.readArrayLength(StaticSerialization.java:102)
        at 
org.apache.geode.internal.serialization.StaticSerialization.readByteArray(StaticSerialization.java:321)
        at 
org.apache.geode.internal.serialization.StaticSerialization.readInetAddress(StaticSerialization.java:254)
        at 
org.apache.geode.DataSerializer.readInetAddress(DataSerializer.java:463)
        at 
org.apache.geode.distributed.internal.membership.InternalDistributedMember._readEssentialData(InternalDistributedMember.java:1085)
        at 
org.apache.geode.distributed.internal.membership.InternalDistributedMember.readEssentialData(InternalDistributedMember.java:1079)
        at 
org.apache.geode.internal.cache.versions.VMVersionTag.readMember(VMVersionTag.java:58)
        at 
org.apache.geode.internal.cache.versions.VMVersionTag.readMember(VMVersionTag.java:31)
        at 
org.apache.geode.internal.cache.versions.VersionTag.fromData(VersionTag.java:412)
        at 
org.apache.geode.internal.serialization.DSFIDSerializerImpl.invokeFromData(DSFIDSerializerImpl.java:300)
        at 
org.apache.geode.internal.serialization.DSFIDSerializerImpl.create(DSFIDSerializerImpl.java:347)
        at org.apache.geode.internal.DSFIDFactory.create(DSFIDFactory.java:1018)
        at 
org.apache.geode.internal.InternalDataSerializer.basicReadObject(InternalDataSerializer.java:2639)
        at org.apache.geode.DataSerializer.readObject(DataSerializer.java:2864)
        at 
org.apache.geode.internal.cache.partitioned.PutMessage$PutReplyMessage.fromData(PutMessage.java:940)
        at 
org.apache.geode.internal.serialization.DSFIDSerializerImpl.invokeFromData(DSFIDSerializerImpl.java:300)
        at 
org.apache.geode.internal.serialization.DSFIDSerializerImpl.create(DSFIDSerializerImpl.java:347)
        at org.apache.geode.internal.DSFIDFactory.create(DSFIDFactory.java:1018)
        at 
org.apache.geode.internal.InternalDataSerializer.readDSFID(InternalDataSerializer.java:2520)
        at 
org.apache.geode.internal.InternalDataSerializer.readDSFID(InternalDataSerializer.java:2534)
        at 
org.apache.geode.internal.tcp.Connection.readMessage(Connection.java:3118)
        at 
org.apache.geode.internal.tcp.Connection.processInputBuffer(Connection.java:2927)
        at 
org.apache.geode.internal.tcp.Connection.readMessages(Connection.java:1752)
        at org.apache.geode.internal.tcp.Connection.run(Connection.java:1584)
        at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
{noformat}

This code is trying to read a "previous member ID" for the version tag but 
there isn't one.  The decision to write one or not comes from this code:

{code}
    if (this.previousMemberID != null
        && (this.previousMemberID != this.memberID || !includeMember)) {
      writeMember(this.previousMemberID, out);
    }
{code}

but flags have already been written telling deserialization code whether or not 
to read this field:

{code}
    if (this.previousMemberID != null) {
      flags |= HAS_PREVIOUS_MEMBER_ID;
      if (this.previousMemberID == this.memberID && includeMember) {
        flags |= DUPLICATE_MEMBER_IDS;
      }
    }
{code}

If the previousMemberID is canonicalized while this method is being processed 
the flags may not agree with the decision made by the code invoking 
writeMember().  That code ought to be changed to respect the flags that were 
set earlier in the method.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to