1 #!/bin/sh
   2 
   3 #
   4 # Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
   5 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6 #
   7 # This code is free software; you can redistribute it and/or modify it
   8 # under the terms of the GNU General Public License version 2 only, as
   9 # published by the Free Software Foundation.
  10 #
  11 # This code is distributed in the hope that it will be useful, but WITHOUT
  12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14 # version 2 for more details (a copy is included in the LICENSE file that
  15 # accompanied this code).
  16 #
  17 # You should have received a copy of the GNU General Public License version
  18 # 2 along with this work; if not, write to the Free Software Foundation,
  19 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20 #
  21 # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22 # or visit www.oracle.com if you need additional information or have any
  23 # questions.
  24 #
  25 
  26 # @test
  27 # @bug 6202891
  28 # @summary TTY: Add support for method exit event return values to jdb
  29 # @author Jim Holmlund
  30 #
  31 # @run shell JdbMethodExitTest.sh
  32 
  33 # These are variables that can be set to control execution
  34 
  35 #pkg=untitled7
  36 classname=JdbMethodExitTest
  37 compileOptions=-g
  38 #java="java_g"
  39 #set -x
  40 
  41 createJavaFile()
  42 {
  43     cat <<EOF > $classname.java.1
  44 import java.util.*;
  45 import java.net.URLClassLoader;
  46 import java.net.URL;
  47 
  48 /*
  49  * This tests the jdb trace command
  50  */
  51 
  52 class $classname {
  53     // These are the values that will be returned by the methods
  54     static URL[] urls = new URL[1];
  55     public static byte      byteValue = 89;
  56     public static char      charValue = 'x';
  57     public static double    doubleValue = 2.2;
  58     public static float     floatValue = 3.3f;
  59     public static int       intValue = 1;
  60     public static short     shortValue = 8;
  61     public static boolean   booleanValue = false;
  62 
  63     public static Class       classValue = Object.class;
  64     public static ClassLoader classLoaderValue;
  65     {
  66         try {
  67             urls[0] = new URL("hi there");
  68         } catch (java.net.MalformedURLException ee) {
  69         }
  70         classLoaderValue = new URLClassLoader(urls);
  71     }
  72 
  73     public static Thread      threadValue;
  74     public static ThreadGroup threadGroupValue;
  75     public static String      stringValue = "abc";
  76     public static int[]       intArrayValue = new int[] {1, 2, 3};
  77 
  78     public static $classname  objectValue =
  79         new $classname();
  80     public String ivar = stringValue;
  81 
  82     // These are the instance methods
  83     public byte i_bytef()            { return byteValue; }
  84     public char i_charf()            { return charValue; }
  85     public double i_doublef()        { return doubleValue; }
  86     public float i_floatf()          { return floatValue; }
  87     public int i_intf()              { return intValue; }
  88     public short i_shortf()          { return shortValue; }
  89     public boolean i_booleanf()      { return booleanValue; }
  90     public String i_stringf()        { return stringValue; }
  91     public Class i_classf()          { return classValue; }
  92     public ClassLoader i_classLoaderf()
  93                                      { return classLoaderValue; }
  94     public Thread i_threadf()        { return threadValue = Thread.currentThread(); }
  95     public ThreadGroup i_threadGroupf()
  96                                      { return threadGroupValue = threadValue.getThreadGroup(); }
  97     public int[] i_intArrayf()       { return intArrayValue; }
  98     public Object i_nullObjectf()    { return null; }
  99     public Object i_objectf()        { return objectValue; }
 100     public void i_voidf()            {}
 101 
 102     static void doit($classname xx) {
 103 
 104         xx.i_bytef();
 105         xx.i_charf();
 106         xx.i_doublef();
 107         xx.i_floatf();
 108         xx.i_intf();
 109         xx.i_shortf();
 110         xx.i_booleanf();
 111         xx.i_stringf();
 112         xx.i_intArrayf();
 113         xx.i_classf();
 114         xx.i_classLoaderf();
 115         xx.i_threadf();
 116         xx.i_threadGroupf();
 117         xx.i_nullObjectf();
 118         xx.i_objectf();
 119         xx.i_voidf();
 120 
 121         // Prove it works for native methods too
 122         StrictMath.sin(doubleValue);
 123         stringValue.intern();
 124     }
 125 
 126     public static void bkpt() {
 127        int i = 0;     //@1 breakpoint
 128     }
 129 
 130     public static String traceMethods() {
 131         return "traceMethods";
 132     }
 133 
 134     public static String traceMethods1() {
 135         return "traceMethods1";
 136     }
 137 
 138     public static String traceExits() {
 139         return "traceExits";
 140     }
 141 
 142     public static String traceExits1() {
 143         return "traceExits1";
 144     }
 145 
 146     public static String traceExit() {
 147         return "traceExit";
 148     }
 149 
 150     public static String traceExit1() {
 151         return "traceExit1";
 152     }
 153 
 154     public static void main(String[] args) {
 155         // The debugger will stop at the start of main,
 156         // enable method exit events, and then do
 157         // a resume.
 158 
 159         $classname xx = new $classname();
 160         System.out.println("threadid="+Thread.currentThread().getId());
 161         bkpt();
 162 
 163         // test all possible return types
 164         doit(xx);
 165         bkpt();
 166 
 167        // test trace methods
 168        traceMethods();
 169 
 170        // test trace go methods
 171        traceMethods1();
 172        bkpt();
 173 
 174        // test trace method exits
 175        traceExits();
 176 
 177        // test trace method exits
 178        traceExits1();
 179        bkpt();
 180 
 181        // test trace method exit
 182        traceExit();
 183 
 184        // test trace method exit
 185        traceExit1();
 186        bkpt();
 187 
 188     }
 189 }
 190 EOF
 191 }
 192 
 193 
 194 # drive jdb by sending cmds to it and examining its output
 195 dojdbCmds()
 196 {
 197     setBkpts @1
 198 
 199     # test all possible return types
 200     runToBkpt @1
 201     debuggeeMatchRegexp "s/threadid=\(.*\)/\1/g"
 202     threadid=$?
 203     cmd untrace
 204 
 205     cmd trace methods
 206     cmd trace
 207     jdbFailIfNotPresent "trace methods in effect"
 208 
 209     cmd trace go methods
 210     cmd trace
 211     jdbFailIfNotPresent "trace go methods in effect"
 212 
 213     cmd trace method exits
 214     cmd trace
 215     jdbFailIfNotPresent "trace method exits in effect"
 216 
 217     cmd trace go method exits
 218     cmd trace
 219     jdbFailIfNotPresent "trace go method exits in effect"
 220 
 221     cmd trace method exit
 222     cmd trace
 223     jdbFailIfNotPresent "trace method exit in effect for JdbMethodExitTest.bkpt"
 224 
 225     cmd trace go method exit
 226     cmd trace
 227     jdbFailIfNotPresent "trace go method exit in effect for JdbMethodExitTest.bkpt"
 228 
 229 
 230     # trace exit of methods with all the return values
 231     # (but just check a couple of them)
 232     cmd trace go method exits $threadid
 233     cmd cont
 234     jdbFailIfNotPresent "instance of JdbMethodExitTest"
 235     jdbFailIfNotPresent "return value = 8"
 236 
 237     # Get out of bkpt back to the call to traceMethods
 238     cmd step up
 239 
 240 
 241     cmd trace methods $threadid
 242     cmd cont
 243     jdbFailIfNotPresent "Method entered:"
 244     cmd cont
 245     jdbFailIfNotPresent "Method exited: return value = \"traceMethods\""
 246     cmd step up
 247 
 248 
 249     cmd trace go methods $threadid
 250     cmd cont
 251     cmd cont
 252     cmd cont
 253     jdbFailIfNotPresent "Method entered: \"thread=main\", JdbMethodExitTest.traceMethods1"
 254     jdbFailIfNotPresent 'Method exited: .* JdbMethodExitTest.traceMethods1'
 255     cmd untrace
 256     cmd step up
 257 
 258 
 259     cmd trace method exits $threadid
 260     cmd cont
 261     jdbFailIfNotPresent "Method exited: return value = \"traceExits\""
 262     cmd untrace
 263     cmd step up
 264 
 265 
 266     cmd trace go method exits $threadid
 267     cmd cont
 268     jdbFailIfNotPresent 'Method exited: .* JdbMethodExitTest.traceExits1'
 269     cmd untrace
 270     cmd step up
 271 
 272 
 273     cmd step            # step into traceExit()
 274     cmd trace method exit $threadid
 275     cmd cont
 276     jdbFailIfNotPresent "Method exited: return value = \"traceExit\""
 277     cmd untrace
 278     cmd step up
 279 
 280 
 281     cmd step
 282     cmd step           # skip over setting return value in caller :-(
 283     cmd trace go method exit $threadid
 284     cmd cont
 285     jdbFailIfNotPresent 'Method exited: .*JdbMethodExitTest.traceExit1'
 286 }
 287 
 288 
 289 mysetup()
 290 {
 291     if [ -z "$TESTSRC" ] ; then
 292         TESTSRC=.
 293     fi
 294 
 295     for ii in . $TESTSRC $TESTSRC/.. ; do
 296         if [ -r "$ii/ShellScaffold.sh" ] ; then
 297             . $ii/ShellScaffold.sh
 298             break
 299         fi
 300     done
 301 }
 302 
 303 # You could replace this next line with the contents
 304 # of ShellScaffold.sh and this script will run just the same.
 305 mysetup
 306 
 307 runit
 308 jdbFailIfNotPresent "Breakpoint hit"
 309 pass