1 /*
   2  * Copyright (c) 2018, 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  * @bug 8193801 8129348
  27  * @summary Invokes static and instance methods when debugger trace
  28  * mode is on.
  29  *
  30  * @library /test/lib
  31  * @run build TestScaffold VMConnection TargetListener TargetAdapter
  32  * @run compile -g MethodInvokeWithTraceOnTest.java
  33  * @run driver MethodInvokeWithTraceOnTest
  34  */
  35 
  36 import com.sun.jdi.*;
  37 import com.sun.jdi.event.*;
  38 
  39 import java.util.*;
  40 
  41 import static lib.jdb.JdbTest.*;
  42 
  43 /********** target program **********/
  44 
  45 class MethodInvokeWithTraceOnTestTarg {
  46     public static void main(String[] args) {
  47         new MethodInvokeWithTraceOnTestTarg().test();
  48     }
  49 
  50     private void test() {
  51         Thread thread = Thread.currentThread();
  52         print(thread); // @1 breakpoint
  53     }
  54 
  55     public void print(Object obj) {
  56         System.out.println(obj);
  57     }
  58 }
  59 
  60 
  61 /********** test program **********/
  62 
  63 public class MethodInvokeWithTraceOnTest extends TestScaffold {
  64 
  65     MethodInvokeWithTraceOnTest(String args[]) {
  66         super(args);
  67     }
  68 
  69     public static void main(String[] args)
  70             throws Exception {
  71         new MethodInvokeWithTraceOnTest(args).startTests();
  72     }
  73 
  74     /********** test core **********/
  75 
  76     protected void runTests()
  77             throws Exception {
  78         BreakpointEvent be = init();
  79         testStaticMethod(be);
  80         testInstanceMethod(be);
  81 
  82         /*
  83          * resume the target listening for events
  84          */
  85         listenUntilVMDisconnect();
  86     }
  87 
  88     private BreakpointEvent init() throws Exception{
  89         startToMain("MethodInvokeWithTraceOnTestTarg");
  90         vm().setDebugTraceMode(VirtualMachine.TRACE_ALL);
  91         int bkpLine = parseBreakpoints(getTestSourcePath("MethodInvokeWithTraceOnTest.java"), 1).get(0);
  92         System.out.println("Running to line: " + bkpLine);
  93         return resumeTo("MethodInvokeWithTraceOnTestTarg", bkpLine);
  94     }
  95 
  96     private void testStaticMethod( BreakpointEvent be) throws Exception {
  97         System.out.println("Testing static method...");
  98         ClassType classType = getClassType("java.lang.Class");
  99         Method forName = classType.methodsByName("forName",
 100                 "(Ljava/lang/String;)Ljava/lang/Class;").get(0);
 101         StringReference classNameParam = vm().mirrorOf("java.lang.String");
 102         classType.invokeMethod(be.thread(), forName, Collections.singletonList(classNameParam), 0);
 103 
 104     }
 105 
 106     private void testInstanceMethod( BreakpointEvent be) throws Exception {
 107         System.out.println("Testing instance method...");
 108         ThreadReference thread = be.thread();
 109         StackFrame frame = thread.frame(0);
 110         ObjectReference thisObj = frame.thisObject();
 111         LocalVariable threadVar = frame.visibleVariableByName("thread");
 112         ThreadReference threadObj = (ThreadReference)frame.getValue(threadVar);
 113 
 114         ClassType classType = (ClassType)thisObj.referenceType();
 115         for(Method m: classType.methods()){
 116             System.out.println(m.signature() + ":" + m.name());
 117         }
 118         Method printMethod = classType.methodsByName("print",
 119                 "(Ljava/lang/Object;)V").get(0);
 120         StringReference objectToPrint = vm().mirrorOf("test string");
 121         System.out.println("Passing StringReference to instance method...");
 122         thisObj.invokeMethod(thread, printMethod, Collections.singletonList(objectToPrint), 0);
 123         System.out.println("Passing ThreadReference to instance method...");
 124         thisObj.invokeMethod(thread, printMethod, Collections.singletonList(threadObj), 0);
 125 
 126     }
 127 
 128     private ClassType getClassType(String className) throws Exception {
 129         List classes = vm().classesByName(className);
 130         return (ClassType) classes.get(0);
 131     }
 132 
 133 }