Path: blob/master/test/hotspot/jtreg/serviceability/sa/ClhsdbFindPC.java
41149 views
/*1* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.util.HashMap;24import java.util.List;25import java.util.Map;26import java.util.ArrayList;2728import jdk.test.lib.apps.LingeredApp;29import jdk.test.lib.Platform;30import jdk.test.lib.util.CoreUtils;31import jtreg.SkippedException;3233/**34* @test35* @bug 819312436* @summary Test the clhsdb 'findpc' command with Xcomp on live process37* @requires vm.hasSA38* @requires vm.compiler1.enabled39* @requires vm.opt.DeoptimizeALot != true40* @library /test/lib41* @run main/othervm/timeout=480 ClhsdbFindPC true false42*/4344/**45* @test46* @bug 819312447* @summary Test the clhsdb 'findpc' command with Xcomp on core file48* @requires vm.compMode != "Xcomp"49* @requires vm.hasSA50* @requires vm.compiler1.enabled51* @library /test/lib52* @run main/othervm/timeout=480 ClhsdbFindPC true true53*/5455/**56* @test57* @bug 819312458* @summary Test the clhsdb 'findpc' command w/o Xcomp on live process59* @requires vm.hasSA60* @requires vm.compiler1.enabled61* @requires vm.opt.DeoptimizeALot != true62* @library /test/lib63* @run main/othervm/timeout=480 ClhsdbFindPC false false64*/6566/**67* @test68* @bug 819312469* @summary Test the clhsdb 'findpc' command w/o Xcomp on core file70* @requires vm.compMode != "Xcomp"71* @requires vm.hasSA72* @requires vm.compiler1.enabled73* @library /test/lib74* @run main/othervm/timeout=480 ClhsdbFindPC false true75*/7677public class ClhsdbFindPC {78static LingeredApp theApp = null;79static String coreFileName = null;80static ClhsdbLauncher test = null;8182private static void testFindPC(boolean withXcomp, boolean withCore) throws Exception {83try {84String linesep = System.getProperty("line.separator");85String segvAddress = null;86List<String> cmds = null;87String cmdStr = null;88Map<String, List<String>> expStrMap = null;8990test = new ClhsdbLauncher();9192theApp = new LingeredApp();93theApp.setForceCrash(withCore);94if (withXcomp) {95LingeredApp.startApp(theApp, "-Xcomp");96} else {97LingeredApp.startApp(theApp, "-Xint");98}99System.out.print("Started LingeredApp ");100if (withXcomp) {101System.out.print("(-Xcomp) ");102} else {103System.out.print("(-Xint) ");104}105System.out.println("with pid " + theApp.getPid());106107if (withCore) {108String crashOutput = theApp.getOutput().getStdout();109// Get the core file name if we are debugging a core instead of live process110coreFileName = CoreUtils.getCoreFileLocation(crashOutput, theApp.getPid());111// Get the SEGV Address from the following line:112// # SIGSEGV (0xb) at pc=0x00007f20a897f7f4, pid=8561, tid=8562113String[] parts = crashOutput.split(" pc=");114String[] tokens = parts[1].split(",");115segvAddress = tokens[0];116117// Test the 'findpc' command passing in the SEGV address118cmds = new ArrayList<String>();119cmdStr = "findpc " + segvAddress;120cmds.add(cmdStr);121expStrMap = new HashMap<>();122if (Platform.isOSX()) {123// OSX will only find addresses in JVM libraries, not user or system libraries124expStrMap.put(cmdStr, List.of("In unknown location"));125} else { // symbol lookups not supported with OSX live process126expStrMap.put(cmdStr, List.of("Java_jdk_test_lib_apps_LingeredApp_crash"));127}128runTest(withCore, cmds, expStrMap);129}130131// Run 'jstack -v' command to get the pc and other useful values132cmds = List.of("jstack -v");133String jStackOutput = runTest(withCore, cmds, null);134135// Extract pc address from the following line:136// - LingeredApp.steadyState(java.lang.Object) @bci=1, line=33, pc=0x00007ff18ff519f0, ...137String pcAddress = null;138String[] parts = jStackOutput.split("LingeredApp.steadyState");139String[] tokens = parts[1].split(" ");140for (String token : tokens) {141if (token.contains("pc")) {142String[] addresses = token.split("=");143// addresses[1] represents the address of the Method144pcAddress = addresses[1].replace(",","");145break;146}147}148if (pcAddress == null) {149throw new RuntimeException("Cannot find LingeredApp.steadyState pc in output");150}151152// Test the 'findpc' command passing in the pc obtained from jstack above153cmds = new ArrayList<String>();154cmdStr = "findpc " + pcAddress;155cmds.add(cmdStr);156expStrMap = new HashMap<>();157if (withXcomp) {158expStrMap.put(cmdStr, List.of(159"In code in NMethod for jdk/test/lib/apps/LingeredApp.steadyState",160"content:",161"oops:",162"frame size:"));163} else {164expStrMap.put(cmdStr, List.of(165"In interpreter codelet"));166}167runTest(withCore, cmds, expStrMap);168169// Run findpc on a Method*. We can find one in the jstack output. For example:170// - LingeredApp.steadyState(java.lang.Object) @bci=1, line=33, pc=..., Method*=0x0000008041000208 ...171// This is testing the PointerFinder support for C++ MetaData types.172parts = jStackOutput.split("LingeredApp.steadyState");173parts = parts[1].split("Method\\*=");174parts = parts[1].split(" ");175String methodAddr = parts[0];176cmdStr = "findpc " + methodAddr;177cmds = List.of(cmdStr);178expStrMap = new HashMap<>();179expStrMap.put(cmdStr, List.of("Method ",180"LingeredApp.steadyState",181methodAddr));182runTest(withCore, cmds, expStrMap);183184// Run findpc on a JavaThread*. We can find one in the jstack output.185// The tid for a thread is it's JavaThread*. For example:186// "main" #1 prio=5 tid=0x00000080263398f0 nid=0x277e0 ...187// This is testing the PointerFinder support for all C++ types other than MetaData types.188parts = jStackOutput.split("tid=");189parts = parts[1].split(" ");190String tid = parts[0]; // address of the JavaThread191cmdStr = "findpc " + tid;192cmds = List.of(cmdStr);193expStrMap = new HashMap<>();194expStrMap.put(cmdStr, List.of("Is of type JavaThread"));195runTest(withCore, cmds, expStrMap);196197// Run findpc on a java stack address. We can find one in the jstack output.198// "main" #1 prio=5 tid=... nid=0x277e0 waiting on condition [0x0000008025aef000]199// The stack address is the last word between the brackets.200// This is testing the PointerFinder support for thread stack addresses.201parts = jStackOutput.split("tid=");202parts = parts[1].split(" \\[");203parts = parts[1].split("\\]");204String stackAddress = parts[0]; // address of the thread's stack205if (Long.decode(stackAddress) == 0L) {206System.out.println("Stack address is " + stackAddress + ". Skipping test.");207} else {208cmdStr = "findpc " + stackAddress;209cmds = List.of(cmdStr);210expStrMap = new HashMap<>();211expStrMap.put(cmdStr, List.of("In java stack"));212runTest(withCore, cmds, expStrMap);213}214215// Run 'examine <addr>' using a thread's tid as the address. The216// examine output will be the of the form:217// <tid>: <value>218// Where <value> is the word stored at <tid>. <value> also happens to219// be the vtable address. We then run findpc on this vtable address.220// This tests PointerFinder support for native C++ symbols.221cmds = List.of("examine " + tid);222String examineOutput = runTest(withCore, cmds, null);223// Extract <value>.224parts = examineOutput.split(tid + ": ");225String value = parts[1].split(linesep)[0];226// Use findpc on <value>. The output should look something like:227// Address 0x00007fed86f610b8: vtable for JavaThread + 0x10228cmdStr = "findpc " + value;229cmds = List.of(cmdStr);230expStrMap = new HashMap<>();231if (Platform.isWindows()) {232expStrMap.put(cmdStr, List.of("jvm.+JavaThread"));233} else if (Platform.isOSX()) {234if (withCore) {235expStrMap.put(cmdStr, List.of("__ZTV10JavaThread"));236} else { // address -> symbol lookups not supported with OSX live process237expStrMap.put(cmdStr, List.of("In unknown location"));238}239} else {240expStrMap.put(cmdStr, List.of("vtable for JavaThread"));241}242String findpcOutput = runTest(withCore, cmds, expStrMap);243244// Determine if we have symbol support. Currently we assume yes except on windows.245boolean hasSymbols = true;246if (Platform.isWindows()) {247if (findpcOutput.indexOf("jvm!JavaThread::`vftable'") == -1) {248hasSymbols = false;249}250}251252// Run "findsym MaxJNILocalCapacity". The output should look something like:253// 0x00007eff8e1a0da0: <jdk-dir>/lib/server/libjvm.so + 0x1d81da0254String symbol = "MaxJNILocalCapacity";255cmds = List.of("findsym " + symbol);256expStrMap = new HashMap<>();257if (!hasSymbols) {258expStrMap.put(cmdStr, List.of("Symbol not found"));259}260String findsymOutput = runTest(withCore, cmds, expStrMap);261// Run findpc on the result of "findsym MaxJNILocalCapacity". The output262// should look something like:263// Address 0x00007eff8e1a0da0: MaxJNILocalCapacity264if (hasSymbols) {265parts = findsymOutput.split("findsym " + symbol + linesep);266parts = parts[1].split(":");267String findsymAddress = parts[0].split(linesep)[0];268cmdStr = "findpc " + findsymAddress;269cmds = List.of(cmdStr);270expStrMap = new HashMap<>();271if (Platform.isOSX() && !withCore) {272// address -> symbol lookups not supported with OSX live process273expStrMap.put(cmdStr, List.of("Address " + findsymAddress + ": In unknown location"));274} else {275expStrMap.put(cmdStr, List.of("Address " + findsymAddress + ": .*" + symbol));276}277runTest(withCore, cmds, expStrMap);278}279} catch (SkippedException se) {280throw se;281} catch (Exception ex) {282throw new RuntimeException("Test ERROR " + ex, ex);283} finally {284if (!withCore) {285LingeredApp.stopApp(theApp);286}287}288}289290private static String runTest(boolean withCore, List<String> cmds, Map<String, List<String>> expStrMap)291throws Exception292{293if (withCore) {294return test.runOnCore(coreFileName, cmds, expStrMap, null);295} else {296return test.run(theApp.getPid(), cmds, expStrMap, null);297}298}299300public static void main(String[] args) throws Exception {301boolean withXcomp = Boolean.parseBoolean(args[0]);302boolean withCore = Boolean.parseBoolean(args[1]);303System.out.println("Starting the ClhsdbFindPC test");304testFindPC(withXcomp, withCore);305System.out.println("Test PASSED");306}307}308309310