Path: blob/master/test/hotspot/jtreg/serviceability/sa/ClhsdbFindPC.java
64478 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<>();211// Note, sometimes a stack address points to a hotspot type, thus allow for "Is of type".212expStrMap.put(cmdStr, List.of("(In java stack)|(Is of type)"));213runTest(withCore, cmds, expStrMap);214}215216// Run 'examine <addr>' using a thread's tid as the address. The217// examine output will be the of the form:218// <tid>: <value>219// Where <value> is the word stored at <tid>. <value> also happens to220// be the vtable address. We then run findpc on this vtable address.221// This tests PointerFinder support for native C++ symbols.222cmds = List.of("examine " + tid);223String examineOutput = runTest(withCore, cmds, null);224// Extract <value>.225parts = examineOutput.split(tid + ": ");226String value = parts[1].split(linesep)[0];227// Use findpc on <value>. The output should look something like:228// Address 0x00007fed86f610b8: vtable for JavaThread + 0x10229cmdStr = "findpc " + value;230cmds = List.of(cmdStr);231expStrMap = new HashMap<>();232if (Platform.isWindows()) {233expStrMap.put(cmdStr, List.of("jvm.+JavaThread"));234} else if (Platform.isOSX()) {235if (withCore) {236expStrMap.put(cmdStr, List.of("__ZTV10JavaThread"));237} else { // address -> symbol lookups not supported with OSX live process238expStrMap.put(cmdStr, List.of("In unknown location"));239}240} else {241expStrMap.put(cmdStr, List.of("vtable for JavaThread"));242}243String findpcOutput = runTest(withCore, cmds, expStrMap);244245// Determine if we have symbol support. Currently we assume yes except on windows.246boolean hasSymbols = true;247if (Platform.isWindows()) {248if (findpcOutput.indexOf("jvm!JavaThread::`vftable'") == -1) {249hasSymbols = false;250}251}252253// Run "findsym MaxJNILocalCapacity". The output should look something like:254// 0x00007eff8e1a0da0: <jdk-dir>/lib/server/libjvm.so + 0x1d81da0255String symbol = "MaxJNILocalCapacity";256cmds = List.of("findsym " + symbol);257expStrMap = new HashMap<>();258if (!hasSymbols) {259expStrMap.put(cmdStr, List.of("Symbol not found"));260}261String findsymOutput = runTest(withCore, cmds, expStrMap);262// Run findpc on the result of "findsym MaxJNILocalCapacity". The output263// should look something like:264// Address 0x00007eff8e1a0da0: MaxJNILocalCapacity265if (hasSymbols) {266parts = findsymOutput.split("findsym " + symbol + linesep);267parts = parts[1].split(":");268String findsymAddress = parts[0].split(linesep)[0];269cmdStr = "findpc " + findsymAddress;270cmds = List.of(cmdStr);271expStrMap = new HashMap<>();272if (Platform.isOSX() && !withCore) {273// address -> symbol lookups not supported with OSX live process274expStrMap.put(cmdStr, List.of("Address " + findsymAddress + ": In unknown location"));275} else {276expStrMap.put(cmdStr, List.of("Address " + findsymAddress + ": .*" + symbol));277}278runTest(withCore, cmds, expStrMap);279}280} catch (SkippedException se) {281throw se;282} catch (Exception ex) {283throw new RuntimeException("Test ERROR " + ex, ex);284} finally {285if (!withCore) {286LingeredApp.stopApp(theApp);287}288}289}290291private static String runTest(boolean withCore, List<String> cmds, Map<String, List<String>> expStrMap)292throws Exception293{294if (withCore) {295return test.runOnCore(coreFileName, cmds, expStrMap, null);296} else {297return test.run(theApp.getPid(), cmds, expStrMap, null);298}299}300301public static void main(String[] args) throws Exception {302boolean withXcomp = Boolean.parseBoolean(args[0]);303boolean withCore = Boolean.parseBoolean(args[1]);304System.out.println("Starting the ClhsdbFindPC test");305testFindPC(withXcomp, withCore);306System.out.println("Test PASSED");307}308}309310311