1 /* 2 * Copyright (c) 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 24 /* 25 * @test 26 * @key nmt 27 * @summary Running with NMT detail should produce expected stack traces. 28 * @library /test/lib 29 * @modules java.base/jdk.internal.misc 30 * java.management 31 */ 32 33 import jdk.test.lib.Platform; 34 import jdk.test.lib.process.ProcessTools; 35 import jdk.test.lib.process.OutputAnalyzer; 36 import java.util.regex.Matcher; 37 import java.util.regex.Pattern; 38 39 public class CheckForProperDetailStackTrace { 40 /* The stack trace we look for by default. Note that :: has been replaced by .* 41 to make sure it maches even if the symbol is not unmangled. */ 42 public static String stackTraceDefault = 43 ".*ModuleEntryTable.*new_entry.*\n" + 44 ".*ModuleEntryTable.*locked_create_entry_or_null.*\n" + 45 ".*Modules.*define_module.*\n" + 46 ".*JVM_DefineModule.*\n"; 47 48 /* The stack trace we look for on Solaris and Windows slowdebug builds. For some 49 reason ALWAYSINLINE for AllocateHeap is ignored, so it appears in the stack strace. */ 50 public static String stackTraceAllocateHeap = 51 ".*AllocateHeap.*\n" + 52 ".*ModuleEntryTable.*new_entry.*\n" + 53 ".*ModuleEntryTable.*locked_create_entry_or_null.*\n" + 54 ".*Modules.*define_module.*\n"; 55 56 /* A symbol that should always be present in NMT detail output. */ 57 private static String expectedSymbol = 58 "locked_create_entry_or_null"; 59 60 public static void main(String args[]) throws Exception { 61 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 62 "-XX:+UnlockDiagnosticVMOptions", 63 "-XX:NativeMemoryTracking=detail", 64 "-XX:+PrintNMTStatistics", 65 "-version"); 66 OutputAnalyzer output = new OutputAnalyzer(pb.start()); 67 68 output.shouldHaveExitValue(0); 69 70 // We should never see either of these frames because they are supposed to be skipped. */ 71 output.shouldNotContain("NativeCallStack::NativeCallStack"); 72 output.shouldNotContain("os::get_native_stack"); 73 74 // AllocateHeap shouldn't be in the output because it is supposed to always be inlined. 75 // We check for that here, but allow it for Aix, Solaris and Windows slowdebug builds 76 // because the compiler ends up not inlining AllocateHeap. 77 Boolean okToHaveAllocateHeap = 78 Platform.isSlowDebugBuild() && 79 (Platform.isAix() || Platform.isSolaris() || Platform.isWindows()); 80 if (!okToHaveAllocateHeap) { 81 output.shouldNotContain("AllocateHeap"); 82 } 83 84 // See if we have any stack trace symbols in the output 85 boolean hasSymbols = 86 output.getStdout().contains(expectedSymbol) || output.getStderr().contains(expectedSymbol); 87 if (!hasSymbols) { 88 // It's ok for ARM not to have symbols, because it does not support NMT detail 89 // when targeting thumb2. It's also ok for Windows not to have symbols, because 90 // they are only available if the symbols file is included with the build. 91 if (Platform.isWindows() || Platform.isARM()) { 92 return; // we are done 93 } 94 output.reportDiagnosticSummary(); 95 throw new RuntimeException("Expected symbol missing missing from output: " + expectedSymbol); 96 } 97 98 /* Make sure the expected NMT detail stack trace is found. */ 99 String expectedStackTrace = 100 (okToHaveAllocateHeap ? stackTraceAllocateHeap : stackTraceDefault); 101 if (!stackTraceMatches(expectedStackTrace, output)) { 102 output.reportDiagnosticSummary(); 103 throw new RuntimeException("Expected stack trace missing missing from output: " + expectedStackTrace); 104 } 105 } 106 107 public static boolean stackTraceMatches(String stackTrace, OutputAnalyzer output) { 108 Matcher stdoutMatcher = Pattern.compile(stackTrace, Pattern.MULTILINE).matcher(output.getStdout()); 109 Matcher stderrMatcher = Pattern.compile(stackTrace, Pattern.MULTILINE).matcher(output.getStderr()); 110 return (stdoutMatcher.find() || stderrMatcher.find()); 111 } 112 }