In message <[email protected]>,
Mark Hindess writes:
>
> In message <[email protected]>, Tim Ellison writes:
> >
> > On 11/Sep/2009 23:13, Mark Hindess wrote:
> > > I am trying to work through the JDWP java6 branch test failures
> > > (so is Oliver). I see quite a lot of intermittent failures on
> > > Linux[0]. I think they are mostly caused by failures at the time
> > > when the socket used for synchronising the debuggee/debugger
> > > is being closed. The sychronisation is simply one end calling
> > > "DataOutputStream.writeUTF("continue"); DataOutputStream.flush();" and
> > > the other end trying to do DataInputStream.readUTF().
> > >
> > > When running on the RI, the tests pass consistently. Strace of the RI
> > > shows the writeUTF making syscalls like:
> > >
> > > send(10, "\0\10continue", 10, 0) = 10
> > > close(10) = 0
> > >
> > > where as our implementation does:
> > >
> > > send(58, "\0\10", 2, 0) = 2
> > > send(58, "continue", 8, 0) = 8
> > > close(58) = 0
> > >
> > > Examining the packet dump for the socket shows a packet containing the
> > > length ('\0\10') followed by a RST packet as the socket is closed but no
> > > packet containing the "continue" text. So, the "continue" is lost with
> > > the result that the other end reads the length then loops waiting for
> > > the message until the test timeout is reached.[1]
> > >
> > > I think it would probably be useful if we fixed our implementation to
> > > have the same behaviour as the RI.
> >
> > +1
> >
> > I'm happy to take a look at that if you want.
>
> Well, just doing the obvious thing of re-writing writeUTF by moving
> the code from writeUTFBytes (and making utfBytes two bytes larger to
> insert the length) into writeUTF seems to fix at least some of the
> intermittent failures for me. (I've appended the patch but it doesn't
> really show what I did particularly well.) But I've not run the luni
> tests on this change yet and I need sleep now.
I've done a few jdwp test runs now and this approach definitely improves
stability quite a bit. Unfortunately ObjectOutputStream uses the
writeUTFBytes method that my patch removes so it needs more work. I
wonder whether the ObjectOutputStream implementation suffers from the
same issue.
-Mark.
> And I still want to figure out why the test framework missed the close.
>
> Regards,
> Mark.
>
> > > Regards,
> > > Mark.
> > >
> > > [0] I'm using org.apache.harmony.jpda.tests.jdwp.MultiSession.RefTypeIDTe
> st
> > > for testing but there are plenty of intermittently failing tests to
> > > choose from.
> > >
> > > [1] I wonder why doesn't it see the socket close and bail out? This is
> > > probably another bug (perhaps with the framework).
>
> Index: modules/luni/src/main/java/java/io/DataOutputStream.java
> ===================================================================
> --- modules/luni/src/main/java/java/io/DataOutputStream.java (revision 81373
> 9)
> +++ modules/luni/src/main/java/java/io/DataOutputStream.java (working copy)
> @@ -314,30 +314,12 @@
> if (utfCount > 65535) {
> throw new UTFDataFormatException(Msg.getString("K0068")); //$NON
> -NLS-1$
> }
> - writeShort((int) utfCount);
> - writeUTFBytes(str, utfCount);
> - }
> -
> - long countUTFBytes(String str) {
> - int utfCount = 0, length = str.length();
> - for (int i = 0; i < length; i++) {
> - int charValue = str.charAt(i);
> - if (charValue > 0 && charValue <= 127) {
> - utfCount++;
> - } else if (charValue <= 2047) {
> - utfCount += 2;
> - } else {
> - utfCount += 3;
> - }
> - }
> - return utfCount;
> - }
> -
> - void writeUTFBytes(String str, long count) throws IOException {
> - int size = (int) count;
> + int size = (int) utfCount;
> int length = str.length();
> - byte[] utfBytes = new byte[size];
> + byte[] utfBytes = new byte[size+2];
> int utfIndex = 0;
> + utfBytes[utfIndex++] = (byte) (size >> 8);
> + utfBytes[utfIndex++] = (byte) size;
> for (int i = 0; i < length; i++) {
> int charValue = str.charAt(i);
> if (charValue > 0 && charValue <= 127) {
> @@ -353,4 +335,19 @@
> }
> write(utfBytes, 0, utfIndex);
> }
> +
> + long countUTFBytes(String str) {
> + int utfCount = 0, length = str.length();
> + for (int i = 0; i < length; i++) {
> + int charValue = str.charAt(i);
> + if (charValue > 0 && charValue <= 127) {
> + utfCount++;
> + } else if (charValue <= 2047) {
> + utfCount += 2;
> + } else {
> + utfCount += 3;
> + }
> + }
> + return utfCount;
> + }
> }
>