1 /* 2 * Copyright (c) 2016, 2019, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package jdk.jfr.jvm; 26 27 import java.io.IOException; 28 import java.nio.file.Files; 29 import java.nio.file.Path; 30 import java.nio.file.Paths; 31 import java.util.List; 32 33 import jdk.internal.misc.Unsafe; 34 import jdk.jfr.consumer.RecordedEvent; 35 import jdk.jfr.consumer.RecordingFile; 36 import jdk.test.lib.Asserts; 37 import jdk.test.lib.process.OutputAnalyzer; 38 import jdk.test.lib.process.ProcessTools; 39 40 /** 41 * @test 42 * @key jfr 43 * @summary Verifies that data associated with a running recording can be evacuated to an hs_err_pidXXX.jfr when the VM crashes 44 * @requires vm.hasJFR 45 * 46 * @library /test/lib 47 * @modules java.base/jdk.internal.misc 48 * java.management 49 * jdk.jfr 50 * 51 * @run main/othervm --add-exports=java.base/jdk.internal.misc=ALL-UNNAMED jdk.jfr.jvm.TestDumpOnCrash 52 */ 53 public class TestDumpOnCrash { 54 55 private static final CharSequence LOG_FILE_EXTENSION = ".log"; 56 private static final CharSequence JFR_FILE_EXTENSION = ".jfr"; 57 58 static class CrasherIllegalAccess { main(String[] args)59 public static void main(String[] args) { 60 Unsafe.getUnsafe().putInt(0L, 0); 61 } 62 } 63 64 static class CrasherHalt { main(String[] args)65 public static void main(String[] args) { 66 System.out.println("Running Runtime.getRuntime.halt"); 67 Runtime.getRuntime().halt(17); 68 } 69 } 70 71 static class CrasherSig { main(String[] args)72 public static void main(String[] args) throws Exception { 73 String signalName = args[0]; 74 System.out.println("Sending SIG" + signalName + " to process " + ProcessHandle.current().pid()); 75 Runtime.getRuntime().exec("kill -" + signalName + " " + ProcessHandle.current().pid()).waitFor(); 76 } 77 } 78 main(String[] args)79 public static void main(String[] args) throws Exception { 80 verify(runProcess(CrasherIllegalAccess.class.getName(), "", true)); 81 verify(runProcess(CrasherIllegalAccess.class.getName(), "", false)); 82 verify(runProcess(CrasherHalt.class.getName(), "", true)); 83 verify(runProcess(CrasherHalt.class.getName(), "", false)); 84 85 // Verification is excluded for the test case below until 8219680 is fixed 86 long pid = runProcess(CrasherSig.class.getName(), "FPE", true); 87 // @ignore 8219680 88 // verify(pid); 89 } 90 runProcess(String crasher, String signal, boolean disk)91 private static long runProcess(String crasher, String signal, boolean disk) throws Exception { 92 System.out.println("Test case for crasher " + crasher); 93 final String flightRecordingOptions = "dumponexit=true,disk=" + Boolean.toString(disk); 94 Process p = ProcessTools.createJavaProcessBuilder(true, 95 "-Xmx64m", 96 "-XX:-TransmitErrorReport", 97 "-XX:-CreateCoredumpOnCrash", 98 "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED", 99 "-XX:StartFlightRecording=" + flightRecordingOptions, 100 crasher, 101 signal) 102 .start(); 103 104 OutputAnalyzer output = new OutputAnalyzer(p); 105 System.out.println("========== Crasher process output:"); 106 System.out.println(output.getOutput()); 107 System.out.println("=================================="); 108 109 return p.pid(); 110 } 111 verify(long pid)112 private static void verify(long pid) throws IOException { 113 String fileName = "hs_err_pid" + pid + ".jfr"; 114 Path file = Paths.get(fileName).toAbsolutePath().normalize(); 115 116 Asserts.assertTrue(Files.exists(file), "No emergency jfr recording file " + file + " exists"); 117 Asserts.assertNotEquals(Files.size(file), 0L, "File length 0. Should at least be some bytes"); 118 System.out.printf("File size=%d%n", Files.size(file)); 119 120 List<RecordedEvent> events = RecordingFile.readAllEvents(file); 121 Asserts.assertFalse(events.isEmpty(), "No event found"); 122 System.out.printf("Found event %s%n", events.get(0).getEventType().getName()); 123 } 124 } 125