On 13/Sep/2009 14:28, Mark Hindess wrote: > In message <200909130807.n8d87vgb001...@d12av01.megacenter.de.ibm.com>, Mark > Hi > ndess writes: >> >> In message <200909112249.n8bmnnzb016...@d06av04.portsmouth.uk.ibm.com>, >> Mark Hindess writes: >>> In message <4aaacfce.5090...@gmail.com>, 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 n >> o >>>>> 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. > > Also why does writeUTFBytes(String, long) take a long argument when the > implementation is restricted to int (by the int-sized utfBytes output > buffer)?
Beats me. Reading the code, it is a shame we have to traverse the string twice, once to count the bytes required for UTF-8, and again to perform the encoding. I bet it would be worth speculatively optimizing for ascii (if this ever showed up on a performance benchmark). Regards, Tim >>> 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.RefTypeID >> Te >>> 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 (revisi >> on 81373 >>> 9) >>> +++ modules/luni/src/main/java/java/io/DataOutputStream.java (workin >> g copy) >>> @@ -314,30 +314,12 @@ >>> if (utfCount > 65535) { >>> throw new UTFDataFormatException(Msg.getString("K0068")); //$N >> ON >>> -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; >>> + } >>> } >>> > > >