/*
 * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;

import jdk.test.lib.apps.LingeredApp;
import jdk.test.lib.Platform;
import jdk.test.lib.util.CoreUtils;
import jtreg.SkippedException;

/**
 * @test id=xcomp-process
 * @bug 8193124
 * @summary Test the clhsdb 'findpc' command with Xcomp on live process
 * @requires vm.compMode != "Xcomp"
 * @requires vm.hasSA
 * @requires vm.compiler1.enabled
 * @requires vm.opt.DeoptimizeALot != true
 * @library /test/lib
 * @run main/othervm/timeout=480 ClhsdbFindPC true false
 */

/**
 * @test id=xcomp-core
 * @bug 8193124
 * @summary Test the clhsdb 'findpc' command with Xcomp on core file
 * @requires vm.compMode != "Xcomp"
 * @requires vm.hasSA
 * @requires vm.compiler1.enabled
 * @requires vm.opt.DeoptimizeALot != true
 * @library /test/lib
 * @run main/othervm/timeout=480 ClhsdbFindPC true true
 */

/**
 * @test id=no-xcomp-process
 * @bug 8193124
 * @summary Test the clhsdb 'findpc' command w/o Xcomp on live process
 * @requires vm.hasSA
 * @requires vm.compiler1.enabled
 * @library /test/lib
 * @run main/othervm/timeout=480 ClhsdbFindPC false false
 */

/**
 * @test id=no-xcomp-core
 * @bug 8193124
 * @summary Test the clhsdb 'findpc' command w/o Xcomp on core file
 * @requires vm.hasSA
 * @requires vm.compiler1.enabled
 * @library /test/lib
 * @run main/othervm/timeout=480 ClhsdbFindPC false true
 */

public class ClhsdbFindPC {
    static LingeredApp theApp = null;
    static String coreFileName = null;
    static ClhsdbLauncher test = null;

    private static void testFindPC(boolean withXcomp, boolean withCore) throws Exception {
        try {
            String linesep = System.getProperty("line.separator");
            String segvAddress = null;
            List<String> cmds = null;
            String cmdStr = null;
            Map<String, List<String>> expStrMap = null;

            test = new ClhsdbLauncher();

            theApp = new LingeredApp();
            theApp.setForceCrash(withCore);
            if (withXcomp) {
                LingeredApp.startApp(theApp, "-Xcomp", CoreUtils.getAlwaysPretouchArg(withCore));
            } else {
                LingeredApp.startApp(theApp, "-Xint", CoreUtils.getAlwaysPretouchArg(withCore));
            }
            System.out.print("Started LingeredApp ");
            if (withXcomp) {
                System.out.print("(-Xcomp) ");
            } else {
                System.out.print("(-Xint) ");
            }
            System.out.println("with pid " + theApp.getPid());

            if (withCore) {
                String crashOutput = theApp.getOutput().getStdout();
                // Get the core file name if we are debugging a core instead of live process
                coreFileName = CoreUtils.getCoreFileLocation(crashOutput, theApp.getPid());
                // Get the SEGV Address from the following line:
                //  #  SIGSEGV (0xb) at pc=0x00007f20a897f7f4, pid=8561, tid=8562
                String[] parts = crashOutput.split(" pc=");
                String[] tokens = parts[1].split(",");
                segvAddress = tokens[0];

                // Test the 'findpc' command passing in the SEGV address
                cmds = new ArrayList<String>();
                cmdStr = "findpc " + segvAddress;
                cmds.add(cmdStr);
                expStrMap = new HashMap<>();
                if (Platform.isOSX()) {
                    // OSX will only find addresses in JVM libraries, not user or system libraries
                    expStrMap.put(cmdStr, List.of("In unknown location"));
                } else { // symbol lookups not supported with OSX live process
                    expStrMap.put(cmdStr, List.of("Java_jdk_test_lib_apps_LingeredApp_crash"));
                }
                runTest(withCore, cmds, expStrMap);
            }

            // Run 'jstack -v' command to get the pc and other useful values
            cmds = List.of("jstack -v");
            String jStackOutput = runTest(withCore, cmds, null);

            // Extract pc address from the following line:
            //   - LingeredApp.steadyState(java.lang.Object) @bci=1, line=33, pc=0x00007ff18ff519f0, ...
            String pcAddress = null;
            String[] parts = jStackOutput.split("LingeredApp.steadyState");
            String[] tokens = parts[1].split(" ");
            for (String token : tokens) {
                if (token.contains("pc")) {
                    String[] addresses = token.split("=");
                    // addresses[1] represents the address of the Method
                    pcAddress = addresses[1].replace(",","");
                    break;
                }
            }
            if (pcAddress == null) {
                throw new RuntimeException("Cannot find LingeredApp.steadyState pc in output");
            }

            // Test the 'findpc' command passing in the pc obtained from jstack above
            cmds = new ArrayList<String>();
            cmdStr = "findpc " + pcAddress;
            cmds.add(cmdStr);
            expStrMap = new HashMap<>();
            if (withXcomp) {
                expStrMap.put(cmdStr, List.of(
                            "In code in NMethod for jdk/test/lib/apps/LingeredApp.steadyState",
                            "content:",
                            "oops:",
                            "frame size:"));
            } else {
                expStrMap.put(cmdStr, List.of(
                            "In interpreter codelet"));
            }
            runTest(withCore, cmds, expStrMap);

            // Run findpc on a Method*. We can find one in the jstack output. For example:
            // - LingeredApp.steadyState(java.lang.Object) @bci=1, line=33, pc=..., Method*=0x0000008041000208 ...
            // This is testing the PointerFinder support for C++ MetaData types.
            parts = jStackOutput.split("LingeredApp.steadyState");
            parts = parts[1].split("Method\\*=");
            parts = parts[1].split(" ");
            String methodAddr = parts[0];
            cmdStr = "findpc " + methodAddr;
            cmds = List.of(cmdStr);
            expStrMap = new HashMap<>();
            expStrMap.put(cmdStr, List.of("Method ",
                                          "LingeredApp.steadyState",
                                          methodAddr));
            runTest(withCore, cmds, expStrMap);

            // Rerun above findpc command, but this time using "whatis", which is an alias for "findpc".
            cmdStr = "whatis " + methodAddr;
            cmds = List.of(cmdStr);
            expStrMap = new HashMap<>();
            expStrMap.put(cmdStr, List.of("Method ",
                                          "LingeredApp.steadyState",
                                          methodAddr));
            runTest(withCore, cmds, expStrMap);

            // Run "mem -v <addr>/30" on a Method*. The first line will look like:
            //   Address 0x0000152e30403530: Method jdk/test/lib/apps/LingeredApp.steadyState(Ljava/lang/Object;)V@0x0000152e30403530
            // Followed by lines displaying the memory contents, including interpretation
            // of any contents that are addresses.
            cmdStr = "mem -v " + methodAddr + "/30";
            cmds = List.of(cmdStr);
            expStrMap = new HashMap<>();
            expStrMap.put(cmdStr, List.of("Method jdk/test/lib/apps/LingeredApp.steadyState",
                                          methodAddr,
                                          /* The following is from a field in the Method object. */
                                          "In interpreter codelet: method entry point"));
            runTest(withCore, cmds, expStrMap);

            // Run findpc on a JavaThread*. We can find one in the jstack output.
            // The tid for a thread is it's JavaThread*. For example:
            //  "main" #1 prio=5 tid=0x00000080263398f0 nid=0x277e0 ...
            // This is testing the PointerFinder support for all C++ types other than MetaData types.
            parts = jStackOutput.split("tid=");
            parts = parts[1].split(" ");
            String tid = parts[0];  // address of the JavaThread
            cmdStr = "findpc " + tid;
            cmds = List.of(cmdStr);
            expStrMap = new HashMap<>();
            expStrMap.put(cmdStr, List.of("Is of type JavaThread"));
            runTest(withCore, cmds, expStrMap);

            // Use findpc on an address that is only 4 byte aligned and is the
            // last 4 bytes of a 4k page. This is for testing JDK-8292201.
            String badAddress = tid.substring(0, tid.length() - 3) + "ffc";
            cmdStr = "findpc " + badAddress;
            cmds = List.of(cmdStr);
            expStrMap = new HashMap<>();
            expStrMap.put(cmdStr, List.of("In unknown location"));
            runTest(withCore, cmds, expStrMap);

            // Run findpc on a java stack address. We can find one in the jstack output.
            //   "main" #1 prio=5 tid=... nid=0x277e0 waiting on condition [0x0000008025aef000]
            // The stack address is the last word between the brackets.
            // This is testing the PointerFinder support for thread stack addresses.
            parts = jStackOutput.split("tid=");
            parts = parts[1].split(" \\[");
            parts = parts[1].split("\\]");
            String stackAddress = parts[0];  // address of the thread's stack
            if (Long.decode(stackAddress) == 0L) {
                System.out.println("Stack address is " + stackAddress + ". Skipping test.");
            } else {
                cmdStr = "findpc " + stackAddress;
                cmds = List.of(cmdStr);
                expStrMap = new HashMap<>();
                // Note, sometimes a stack address points to a hotspot type, thus allow for "Is of type".
                expStrMap.put(cmdStr, List.of("(In java stack)|(Is of type)"));
                runTest(withCore, cmds, expStrMap);
            }

            // Run 'examine <addr>' using a thread's tid as the address. The
            // examine output will be the of the form:
            //    <tid>: <value>
            // Where <value> is the word stored at <tid>. <value> also happens to
            // be the vtable address. We then run findpc on this vtable address.
            // This tests PointerFinder support for native C++ symbols.
            cmds = List.of("examine " + tid);
            String examineOutput = runTest(withCore, cmds, null);
            // Extract <value>.
            parts = examineOutput.split(tid + ": ");
            String value = parts[1].split(linesep)[0];
            // Use findpc on <value>. The output should look something like:
            //    Address 0x00007fed86f610b8: vtable for JavaThread + 0x10
            cmdStr = "findpc " + value;
            cmds = List.of(cmdStr);
            expStrMap = new HashMap<>();
            if (Platform.isWindows()) {
                expStrMap.put(cmdStr, List.of("jvm.+JavaThread"));
            } else if (Platform.isOSX()) {
                if (withCore) {
                    expStrMap.put(cmdStr, List.of("__ZTV10JavaThread"));
                } else { // address -> symbol lookups not supported with OSX live process
                    expStrMap.put(cmdStr, List.of("In unknown location"));
                }
            } else {
                expStrMap.put(cmdStr, List.of("vtable for JavaThread"));
            }
            String findpcOutput = runTest(withCore, cmds, expStrMap);

            // Determine if we have symbol support. Currently we assume yes except on windows.
            boolean hasSymbols = true;
            if (Platform.isWindows()) {
                if (findpcOutput.indexOf("jvm!JavaThread::`vftable'") == -1) {
                    hasSymbols = false;
                }
            }

            // Run "findsym MaxJNILocalCapacity". The output should look something like:
            //   0x00007eff8e1a0da0: <jdk-dir>/lib/server/libjvm.so + 0x1d81da0
            String symbol = "MaxJNILocalCapacity";
            cmds = List.of("findsym " + symbol);
            expStrMap = new HashMap<>();
            if (!hasSymbols) {
                expStrMap.put(cmdStr, List.of("Symbol not found"));
            }
            String findsymOutput = runTest(withCore, cmds, expStrMap);
            // Run findpc on the result of "findsym MaxJNILocalCapacity". The output
            // should look something like:
            //   Address 0x00007eff8e1a0da0: MaxJNILocalCapacity
            if (hasSymbols) {
                parts = findsymOutput.split("findsym " + symbol + linesep);
                parts = parts[1].split(":");
                String findsymAddress = parts[0].split(linesep)[0];
                cmdStr = "findpc " + findsymAddress;
                cmds = List.of(cmdStr);
                expStrMap = new HashMap<>();
                if (Platform.isOSX() && !withCore) {
                    // address -> symbol lookups not supported with OSX live process
                    expStrMap.put(cmdStr, List.of("Address " + findsymAddress + ": In unknown location"));
                } else {
                    expStrMap.put(cmdStr, List.of("Address " + findsymAddress + ": .*" + symbol));
                }
                runTest(withCore, cmds, expStrMap);
            }
        } catch (SkippedException se) {
            throw se;
        } catch (Exception ex) {
            throw new RuntimeException("Test ERROR " + ex, ex);
        } finally {
            if (!withCore) {
                LingeredApp.stopApp(theApp);
            }
        }
    }

    private static String runTest(boolean withCore, List<String> cmds, Map<String, List<String>> expStrMap)
        throws Exception
    {
        if (withCore) {
            return test.runOnCore(coreFileName, cmds, expStrMap, null);
        } else {
            return test.run(theApp.getPid(), cmds, expStrMap, null);
        }
    }

    public static void main(String[] args) throws Exception {
        boolean withXcomp = Boolean.parseBoolean(args[0]);
        boolean withCore = Boolean.parseBoolean(args[1]);
        System.out.println("Starting the ClhsdbFindPC test");
        testFindPC(withXcomp, withCore);
        System.out.println("Test PASSED");
    }
}
