1 /*
  2  * Copyright (c) 2014, 2024 SAP SE. All rights reserved.
  3  * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
  4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5  *
  6  * This code is free software; you can redistribute it and/or modify it
  7  * under the terms of the GNU General Public License version 2 only, as
  8  * published by the Free Software Foundation.
  9  *
 10  * This code is distributed in the hope that it will be useful, but WITHOUT
 11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 13  * version 2 for more details (a copy is included in the LICENSE file that
 14  * accompanied this code).
 15  *
 16  * You should have received a copy of the GNU General Public License version
 17  * 2 along with this work; if not, write to the Free Software Foundation,
 18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 19  *
 20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 21  * or visit www.oracle.com if you need additional information or have any
 22  * questions.
 23  */
 24 
 25 
 26 /*
 27  * @test
 28  * @summary Check secondary error handling
 29  * @library /test/lib
 30  * @requires vm.flagless
 31  * @requires vm.debug
 32  * @requires os.family != "windows"
 33  * @modules java.base/jdk.internal.misc
 34  *          java.management
 35  * @run driver SecondaryErrorTest no_callstacks
 36  */
 37 
 38 /*
 39  * @test
 40  * @summary Check secondary error handling
 41  * @library /test/lib
 42  * @requires vm.flagless
 43  * @requires vm.debug
 44  * @requires os.family != "windows"
 45  * @modules java.base/jdk.internal.misc
 46  *          java.management
 47  * @run driver SecondaryErrorTest with_callstacks
 48  */
 49 
 50 import java.io.File;
 51 import java.util.ArrayList;
 52 import java.util.regex.Pattern;
 53 
 54 import jdk.test.lib.process.OutputAnalyzer;
 55 import jdk.test.lib.process.ProcessTools;
 56 
 57 public class SecondaryErrorTest {
 58 
 59 
 60   public static void main(String[] args) throws Exception {
 61 
 62     boolean with_callstacks = false;
 63     if (args.length != 1) {
 64       throw new IllegalArgumentException("Missing argument");
 65     } else if (args[0].equals("with_callstacks")) {
 66       with_callstacks = true;
 67     } else if (args[0].equals("no_callstacks")) {
 68       with_callstacks = false;
 69     } else {
 70       throw new IllegalArgumentException("unknown argument (" + args[0] + ")");
 71     }
 72 
 73     // How this works:
 74     // The test will fault with SIGFPE (ErrorHandlerTest=15) and then, during error handling,
 75     // fault twice with SIGSEGV (TestCrashInErrorHandler=14). The point is not only to test
 76     // secondary crashes, but secondary crashes with a *different* error signal. This should
 77     // be handled correctly and not hang/end the process (so the signal mask must be set correctly).
 78     // See JDK-8065895.
 79     // We do this twice, to check that secondary signal handling works repeatedly.
 80     // We also check, optionally, that +ErrorLogSecondaryErrorDetails produces callstacks for
 81     // the secondary error.
 82 
 83     ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(
 84         "-XX:+UnlockDiagnosticVMOptions",
 85         "-Xmx100M",
 86         "-XX:-CreateCoredumpOnCrash",
 87         "-XX:ErrorHandlerTest=15",
 88         "-XX:TestCrashInErrorHandler=14",
 89         "-XX:" + (with_callstacks ? "+" : "-") + "ErrorLogSecondaryErrorDetails",
 90         "-version");
 91 
 92     OutputAnalyzer output_detail = new OutputAnalyzer(pb.start());
 93 
 94     // we should have crashed with a SIGFPE
 95     output_detail.shouldMatch("# A fatal error has been detected by the Java Runtime Environment:.*");
 96     output_detail.shouldMatch("#.+SIGFPE.*");
 97 
 98     // extract hs-err file
 99     File hs_err_file = HsErrFileUtils.openHsErrFileFromOutput(output_detail);
100 
101     // scan hs-err file: File should contain the "[error occurred during error reporting..]"
102     // markers which show that the secondary error handling kicked in and handled the
103     // error successfully. As an added test, we check that the last line contains "END.",
104     // which is an end marker written in the last step and proves that hs-err file was
105     // completely written.
106 
107     ArrayList<Pattern> patternlist = new ArrayList<>();
108     patternlist.add(Pattern.compile("Will crash now \\(TestCrashInErrorHandler=14\\)..."));
109     patternlist.add(Pattern.compile("\\[error occurred during error reporting \\(test secondary crash 1\\).*\\]"));
110     if (with_callstacks) {
111         patternlist.add(Pattern.compile("\\[siginfo:.*\\(SIGSEGV\\).*\\]"));
112         patternlist.add(Pattern.compile("\\[stack: Native frames:.*"));
113         patternlist.add(Pattern.compile(".*VMError::controlled_crash.*"));
114     }
115     // and again, to see that repeated error reporting steps work
116     patternlist.add(Pattern.compile("Will crash now \\(TestCrashInErrorHandler=14\\)..."));
117     patternlist.add(Pattern.compile("\\[error occurred during error reporting \\(test secondary crash 2\\).*\\]"));
118     if (with_callstacks) {
119         patternlist.add(Pattern.compile("\\[siginfo:.*\\(SIGSEGV\\).*\\]"));
120         patternlist.add(Pattern.compile("\\[stack: Native frames:.*"));
121         patternlist.add(Pattern.compile(".*VMError::controlled_crash.*"));
122     }
123     Pattern[] pattern = patternlist.toArray(new Pattern[] {});
124 
125     HsErrFileUtils.checkHsErrFileContent(hs_err_file, pattern, false, true);
126 
127     System.out.println("OK.");
128 
129   }
130 
131 }
132 
133