1 /* 2 * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package org.graalvm.compiler.hotspot.test; 24 25 import static org.graalvm.compiler.test.SubprocessUtil.getVMCommandLine; 26 import static org.graalvm.compiler.test.SubprocessUtil.withoutDebuggerArguments; 27 28 import java.io.File; 29 import java.io.IOException; 30 import java.util.ArrayList; 31 import java.util.Arrays; 32 import java.util.Enumeration; 33 import java.util.List; 34 import java.util.zip.ZipEntry; 35 import java.util.zip.ZipFile; 36 37 import org.graalvm.compiler.core.test.GraalCompilerTest; 38 import org.graalvm.compiler.test.SubprocessUtil; 39 import org.graalvm.compiler.test.SubprocessUtil.Subprocess; 40 import org.junit.Assert; 41 import org.junit.Test; 42 43 /** 44 * Tests support for dumping graphs and other info useful for debugging a compiler crash. 45 */ 46 public class CompilationWrapperTest extends GraalCompilerTest { 47 48 /** 49 * Tests compilation requested by the VM. 50 */ 51 @Test 52 public void testVMCompilation1() throws IOException, InterruptedException { 53 testHelper(Arrays.asList("-XX:+BootstrapJVMCI", 54 "-XX:+UseJVMCICompiler", 55 "-Dgraal.CompilationFailureAction=ExitVM", 56 "-Dgraal.CrashAt=Object.*,String.*", 57 "-version")); 58 } 59 60 /** 61 * Tests that {@code -Dgraal.ExitVMOnException=true} works as an alias for 62 * {@code -Dgraal.CompilationFailureAction=ExitVM}. 63 */ 64 @Test 65 public void testVMCompilation2() throws IOException, InterruptedException { 66 testHelper(Arrays.asList("-XX:+BootstrapJVMCI", 67 "-XX:+UseJVMCICompiler", 68 "-Dgraal.ExitVMOnException=true", 69 "-Dgraal.CrashAt=Object.*,String.*", 70 "-version")); 71 } 72 73 /** 74 * Tests compilation requested by Truffle. 75 */ 76 @Test 77 public void testTruffleCompilation() throws IOException, InterruptedException { 78 testHelper(Arrays.asList( 79 "-Dgraal.CompilationFailureAction=ExitVM", 80 "-Dgraal.CrashAt=root test1"), 81 "org.graalvm.compiler.truffle.test.SLTruffleGraalTestSuite", 82 "test"); 83 } 84 85 private static void testHelper(List<String> extraVmArgs, String... mainClassAndArgs) throws IOException, InterruptedException { 86 final File dumpPath = new File(CompilationWrapperTest.class.getSimpleName() + "_" + System.currentTimeMillis()).getAbsoluteFile(); 87 List<String> vmArgs = withoutDebuggerArguments(getVMCommandLine()); 88 vmArgs.removeIf(a -> a.startsWith("-Dgraal.")); 89 vmArgs.add("-Dgraal.DumpPath=" + dumpPath); 90 // Force output to a file even if there's a running IGV instance available. 91 vmArgs.add("-Dgraal.PrintGraphFile=true"); 92 vmArgs.addAll(extraVmArgs); 93 94 Subprocess proc = SubprocessUtil.java(vmArgs, mainClassAndArgs); 95 System.out.println(proc); 96 97 String forcedCrashString = "Forced crash after compiling"; 98 String diagnosticOutputFilePrefix = "Graal diagnostic output saved in "; 99 100 boolean seenForcedCrashString = false; 101 String diagnosticOutputZip = null; 102 103 for (String line : proc.output) { 104 if (line.contains(forcedCrashString)) { 105 seenForcedCrashString = true; 106 } else if (diagnosticOutputZip == null) { 107 int index = line.indexOf(diagnosticOutputFilePrefix); 108 if (index != -1) { 109 diagnosticOutputZip = line.substring(diagnosticOutputFilePrefix.length()).trim(); 110 } 111 } 112 } 113 114 if (!seenForcedCrashString) { 115 Assert.fail(String.format("Did not find '%s' in output of command:%n%s", forcedCrashString, proc)); 116 } 117 if (diagnosticOutputZip == null) { 118 Assert.fail(String.format("Did not find '%s' in output of command:%n%s", diagnosticOutputFilePrefix, proc)); 119 } 120 121 String[] dumpPathEntries = dumpPath.list(); 122 123 File zip = new File(diagnosticOutputZip).getAbsoluteFile(); 124 Assert.assertTrue(zip.toString(), zip.exists()); 125 Assert.assertArrayEquals(dumpPathEntries, new String[]{zip.getName()}); 126 try { 127 int bgv = 0; 128 int cfg = 0; 129 ZipFile dd = new ZipFile(diagnosticOutputZip); 130 List<String> entries = new ArrayList<>(); 131 for (Enumeration<? extends ZipEntry> e = dd.entries(); e.hasMoreElements();) { 132 ZipEntry ze = e.nextElement(); 133 String name = ze.getName(); 134 entries.add(name); 135 if (name.endsWith(".bgv")) { 136 bgv++; 137 } else if (name.endsWith(".cfg")) { 138 cfg++; 139 } 140 } 141 if (bgv == 0) { 142 Assert.fail(String.format("Expected at least one .bgv file in %s: %s%n%s", diagnosticOutputZip, entries, proc)); 143 } 144 if (cfg == 0) { 145 Assert.fail(String.format("Expected at least one .cfg file in %s: %s", diagnosticOutputZip, entries)); 146 } 147 } finally { 148 zip.delete(); 149 dumpPath.delete(); 150 } 151 } 152 }