/* * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * @test OomWhileParsingRepeatedJsr * @summary Testing class file parser; specifically parsing * a file with repeated JSR (jump local subroutine) * bytecode command. * @bug 6878713 * @bug 7030610 * @bug 7037122 * @bug 7123945 * @bug 8016029 * @library /testlibrary */ import com.oracle.java.testlibrary.*; import java.io.FileOutputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.file.Path; import java.nio.file.FileSystems; public class OomWhileParsingRepeatedJsr { private static final char[] sClassHeader = { 0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x03, 0x00, 0x2D, 0x00, 0x1A, 0x01, 0x00, 0x0A, 0x53, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6C, 0x65, 0x01, 0x00, 0x0B, 0x3C, 0x67, 0x65, 0x6E, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x3E, 0x01, 0x00, 0x13, 0x4F, 0x4F, 0x4D, 0x43, 0x72, 0x61, 0x73, 0x68, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x31, 0x39, 0x36, 0x30, 0x5F, 0x32, 0x07, 0x00, 0x03, 0x01, 0x00, 0x12, 0x6A, 0x61, 0x76, 0x61, 0x2F, 0x61, 0x70, 0x70, 0x6C, 0x65, 0x74, 0x2F, 0x41, 0x70, 0x70, 0x6C, 0x65, 0x74, 0x07, 0x00, 0x05, 0x01, 0x00, 0x08, 0x70, 0x61, 0x72, 0x73, 0x65, 0x49, 0x6E, 0x74, 0x01, 0x00, 0x15, 0x28, 0x4C, 0x6A, 0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67, 0x2F, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3B, 0x29, 0x49, 0x0C, 0x00, 0x07, 0x00, 0x08, 0x01, 0x00, 0x11, 0x6A, 0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67, 0x2F, 0x49, 0x6E, 0x74, 0x65, 0x67, 0x65, 0x72, 0x07, 0x00, 0x0A, 0x0A, 0x00, 0x0B, 0x00, 0x09, 0x01, 0x00, 0x05, 0x6D, 0x61, 0x69, 0x6E, 0x30, 0x01, 0x00, 0x16, 0x28, 0x5B, 0x4C, 0x6A, 0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67, 0x2F, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3B, 0x29, 0x56, 0x01, 0x00, 0x04, 0x61, 0x72, 0x67, 0x76, 0x01, 0x00, 0x13, 0x5B, 0x4C, 0x6A, 0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67, 0x2F, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3B, 0x01, 0x00, 0x12, 0x4C, 0x6F, 0x63, 0x61, 0x6C, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x54, 0x61, 0x62, 0x6C, 0x65, 0x01, 0x00, 0x04, 0x43, 0x6F, 0x64, 0x65, 0x01, 0x00, 0x05, 0x6D, 0x61, 0x69, 0x6E, 0x31, 0x01, 0x00, 0x06, 0x3C, 0x69, 0x6E, 0x69, 0x74, 0x3E, 0x01, 0x00, 0x03, 0x28, 0x29, 0x56, 0x0C, 0x00, 0x14, 0x00, 0x15, 0x0A, 0x00, 0x06, 0x00, 0x16, 0x01, 0x00, 0x04, 0x74, 0x68, 0x69, 0x73, 0x01, 0x00, 0x15, 0x4C, 0x4F, 0x4F, 0x4D, 0x43, 0x72, 0x61, 0x73, 0x68, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x31, 0x39, 0x36, 0x30, 0x5F, 0x32, 0x3B, 0x00, 0x21, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x09, 0x00, 0x0D, 0x00, 0x0E, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x73, 0x03, 0xFF, 0xFF, 0x00, 0x02, 0x00, 0x00, 0x72, 0xE5, 0x2A, 0x03, 0x32, 0xB8, 0x00, 0x0C, 0x3C, 0xC8, 0x00, 0x00, 0x72, 0xCF, 0xB1, 0x1B, 0x99, 0xFF, 0xFE, 0xA8, 0x00, 0x06, 0xA7, 0x00, 0x04, 0xB1, 0x01, 0xA7, 0xFF, 0xF4 }; private static final char[] sRepeatJsrPattern = {0x1B, 0x99, 0xFF, 0xF0, 0xA8, 0x00, 0x06, 0xA7, 0x00, 0x04, 0xB1, 0x01, 0xA7, 0xFF, 0xF4}; private static final char[] sClassMiddleFragment01 = { 0x00, 0x00, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x72, 0xe5, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x13, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x73, 0x03, 0xff, 0xff, 0x00, 0x02, 0x00, 0x00, 0x72, 0xe5, 0x2a, 0x03, 0x32, 0xb8, 0x00, 0x0c, 0x3c, 0xc8, 0x00, 0x00, 0x72, 0xcf, 0xb1, 0x1b, 0x99, 0xff, 0xfe, 0xa8, 0x00, 0x06, 0xa7, 0x00, 0x04, 0xb1, 0x01, 0xa7, 0xff, 0xf4, 0x1b, 0x99, 0xff, 0xf0, 0xa8, 0x00, 0x06, 0xa7, 0x00, 0x04, 0xb1, 0x01, 0xa7, 0xff, 0xf4 }; private static final char[] sClassFooter = { 0x00, 0x00, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x00, 0x00, 0x72, 0xE5, 0x00, 0x0F, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x14, 0x00, 0x15, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x23, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x2A, 0xB7, 0x00, 0x17, 0xB1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x18, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02 }; private static byte[] toByteArray(char[] input) { byte[] out = new byte[input.length]; int i=0; for (char elem : input) out[i++] = (byte) elem; return out; } // This method is based on reverse engineering of the // OOMCrashClass1960_2 class originally written using JASM // by the original author private static void generateClassFile(String fileName) throws FileNotFoundException, IOException { String path = FileSystems.getDefault().getPath(".", fileName).toAbsolutePath().toString(); System.out.println("Starting to generate classfile " + path); FileOutputStream stream = new FileOutputStream(path); stream.write(toByteArray(sClassHeader)); for (int i=0; i<1959; i++) stream.write(toByteArray(sRepeatJsrPattern)); stream.write(toByteArray(sClassMiddleFragment01)); for (int i=0; i<1958; i++) stream.write(toByteArray(sRepeatJsrPattern)); stream.write(toByteArray(sClassFooter)); stream.close(); } public static void main(String[] args) throws Exception { // ======= Configure the test String className = "OOMCrashClass1960_2"; String classFileName = className + ".class"; // limit is 768MB in native words int mallocMaxTestWords = (1024 * 1024 * 768 / 4); if (Platform.is64bit()) mallocMaxTestWords = (mallocMaxTestWords / 2); // Generate the class file generateClassFile(classFileName); System.out.println("Classfile " + classFileName + " was generated successfully"); // ======= Run the class file ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( "-cp", ".", "-XX:+UnlockDiagnosticVMOptions", "-XX:MallocMaxTestWords=" + mallocMaxTestWords, className); OutputAnalyzer output = new OutputAnalyzer(pb.start()); // ======= Analyze the results String expectedMsg = "Cannot reserve enough memory"; System.out.println("Output is: <<<" + output.getOutput() + ">>>"); output.shouldContain(expectedMsg); } }