On 09/02/2012 20:07, Allen Reese wrote:
> Try again now that I'm subscribed.

If libzip.so is provided by the JVM installer (and I think it is) then
it is still a JVM problem. See [1] for an example where Oracle did
accept that an crash in libzip.so was a bug.

All changing the Tomcat code indicates is that some paths trigger the
bug and some don't. That does not absolve the JVM of responsibility.

Mark

[1] http://bugs.sun.com/view_bug.do?bug_id=6866479

> 
> 
>> -----Original Message-----
>> From: Allen Reese
>> Sent: Thursday, February 09, 2012 12:03 PM
>> To: 'users@tomcat.apache.org'
>> Cc: Lars Anderson
>> Subject: Cores with FlushableGzipOutputStream
>>
>> We've just upgraded from tomcat 6.0.33 to 6.0.35 and started having the
>> JVM core on our production boxes.
>>
>> I'm trying to determine what the next course of action should be here.
>> I have an Oracle Support contract, but they don't seem to see this as a
>> JVM issue, and blame it on a native lib.
>>
>>
>> Thanks.
>>
>> Allen Reese
>> Core Platforms
>> Yahoo!, Inc.
>>
>> Running on linux x86-64, jdk 6u27, 6u29, 6u30, 7u2
>>
>> We run several tests and the output is:
>>
>> Jdk  | Version       | flags
>>      |
>> 6u30 | 6.0.33        | compression enabled
>>      | works
>> 6u30 | 6.0.35        | compression enabled
>>      | cores
>> 6u30 | 6.0.35        | compression disabled
>>      | works
>> 6u30 | 6.0.35        | Remove changes to FlushableGzipOutputStream [1]
>>      | works
>> 6u30 | 6.0.35    | -Dsun.zip.disableMemoryMapping=true
>>      | cores
>>
>> 7u2  | 6.0.35        | compression enabled
>>      | cores
>> 7u2  | 6.0.35        | compression disabled
>>      |
>> 7u2  | 6.0.35        | Remove changes to FlushableGzipOutputStream [1]
>>      |
>> 7u2  | 6.0.35    | -Dsun.zip.disableMemoryMapping=true
>>      | cores
>>
>> https://issues.apache.org/bugzilla/show_bug.cgi?id=52121
>>
>> I filed an SR with Oracle, as this looks like a JVM bug and got the
>> following response:
>>
>> Generic Note
>> ------------------------
>> Hi Allen,
>>
>> Thank you for sending the hotspot error logs (hs_err_pid<pid>). Each
>> one of them has verbiage that indicates the problem is not with Java,
>> but with native code:
>>
>> # Problematic frame:
>> # C [libzip.so+0x77e3] char+0xa3
>> #
>> # If you would like to submit a bug report, please visit:
>> # http://java.sun.com/webapps/bugreport/crash.jsp
>> # The crash happened outside the Java Virtual Machine in native code.
>> # See problematic frame for where to report the bug.
>> #
>>
>> The case description also noted:
>>
>> Rolling back this patch to tomcat increases stability:
>> http://svn.apache.org/viewvc?view=revision&revision=1197382
>>
>> Again, this points to software other than Java. The Java defect
>> mentioned, 4813885, was fixed in June of 2009.
>> =====================
>>
>> Allen Reese
>> Core Platforms
>> Yahoo!, Inc.
>>
>> [1]: Patch to remove changes to FlushableGZIPOutputStream from 6.0.35.
>>
>> --- apache-tomcat-6.0.35-
>> src/java/org/apache/coyote/http11/filters/FlushableGZIPOutputStream.jav
>> a    2011-11-28 02:22:45.000000000 -0800
>> +++ apache-tomcat-6.0.33-
>> src/java/org/apache/coyote/http11/filters/FlushableGZIPOutputStream.jav
>> a    2011-08-16 05:26:14.000000000 -0700
>> @@ -35,93 +35,58 @@
>>          super(os);
>>      }
>>
>> +    private static final byte[] EMPTYBYTEARRAY = new byte[0];
>> +    private boolean hasData = false;
>> +
>>      /**
>> -     * It is used to reserve one byte of real data so that it can be
>> used when
>> -     * flushing the stream.
>> +     * Here we make sure we have received data, so that the header has
>> been for
>> +     * sure written to the output stream already.
>>       */
>> -    private byte[] lastByte = new byte[1];
>> -    private boolean hasLastByte = false;
>> -
>> -    @Override
>> -    public void write(byte[] bytes) throws IOException {
>> -        write(bytes, 0, bytes.length);
>> -    }
>> -
>>      @Override
>> -    public synchronized void write(byte[] bytes, int offset, int
>> length)
>> +    public synchronized void write(byte[] bytes, int i, int i1)
>>              throws IOException {
>> -        if (length > 0) {
>> -            flushLastByte();
>> -            if (length > 1) {
>> -                super.write(bytes, offset, length - 1);
>> -            }
>> -            rememberLastByte(bytes[offset + length - 1]);
>> -        }
>> +        super.write(bytes, i, i1);
>> +        hasData = true;
>>      }
>>
>>      @Override
>>      public synchronized void write(int i) throws IOException {
>> -        flushLastByte();
>> -        rememberLastByte((byte) i);
>> +        super.write(i);
>> +        hasData = true;
>>      }
>>
>>      @Override
>> -    public synchronized void finish() throws IOException {
>> -        try {
>> -            flushLastByte();
>> -        } catch (IOException ignore) {
>> -            // If our write failed, then trailer write in finish()
>> will fail
>> -            // with IOException as well, but it will leave Deflater in
>> more
>> -            // consistent state.
>> -        }
>> -        super.finish();
>> +    public synchronized void write(byte[] bytes) throws IOException {
>> +        super.write(bytes);
>> +        hasData = true;
>>      }
>>
>>      @Override
>> -    public synchronized void close() throws IOException {
>> -        try {
>> -            flushLastByte();
>> -        } catch (IOException ignored) {
>> -            // Ignore. As OutputStream#close() says, the contract of
>> close()
>> -            // is to close the stream. It does not matter much if the
>> -            // stream is not writable any more.
>> +    public synchronized void flush() throws IOException {
>> +        if (!hasData) {
>> +            return; // do not allow the gzip header to be flushed on
>> its own
>>          }
>> -        super.close();
>> -    }
>>
>> -    private void rememberLastByte(byte b) {
>> -        lastByte[0] = b;
>> -        hasLastByte = true;
>> -    }
>> +        // trick the deflater to flush
>> +        /**
>> +         * Now this is tricky: We force the Deflater to flush its data
>> by
>> +         * switching compression level. As yet, a perplexingly simple
>> workaround
>> +         * for
>> +         *
>> http://developer.java.sun.com/developer/bugParade/bugs/4255743.html
>> +         */
>> +        if (!def.finished()) {
>> +            def.setInput(EMPTYBYTEARRAY, 0, 0);
>>
>> -    private void flushLastByte() throws IOException {
>> -        if (hasLastByte) {
>> -            // Clear the flag first, because write() may fail
>> -            hasLastByte = false;
>> -            super.write(lastByte, 0, 1);
>> -        }
>> -    }
>> +            def.setLevel(Deflater.NO_COMPRESSION);
>> +            deflate();
>>
>> -    @Override
>> -    public synchronized void flush() throws IOException {
>> -        if (hasLastByte) {
>> -            // - do not allow the gzip header to be flushed on its own
>> -            // - do not do anything if there is no data to send
>> -
>> -            // trick the deflater to flush
>> -            /**
>> -             * Now this is tricky: We force the Deflater to flush its
>> data by
>> -             * switching compression level. As yet, a perplexingly
>> simple workaround
>> -             * for
>> -             *
>> http://developer.java.sun.com/developer/bugParade/bugs/4255743.html
>> -             */
>> -            if (!def.finished()) {
>> -                def.setLevel(Deflater.NO_COMPRESSION);
>> -                flushLastByte();
>> -                def.setLevel(Deflater.DEFAULT_COMPRESSION);
>> -            }
>> +            def.setLevel(Deflater.DEFAULT_COMPRESSION);
>> +            deflate();
>> +
>> +            out.flush();
>>          }
>> -        out.flush();
>> +
>> +        hasData = false; // no more data to flush
>>      }
>>
>>      /*
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to