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 #  @run shell JdbMethodExitTest.sh
  31 
  32 # These are variables that can be set to control execution
  33 
  34 #pkg=untitled7
  35 classname=JdbMethodExitTest
  36 compileOptions=-g
  37 #java="java_g"
  38 #set -x
  39 
  40 createJavaFile()
  41 {
  42     cat <<EOF > $classname.java.1
  43 import java.util.*;
  44 import java.net.URLClassLoader;
  45 import java.net.URL;
  46 
  47 /*
  48  * This tests the jdb trace command
  49  */
  50 
  51 class $classname {
  52     // These are the values that will be returned by the methods
  53     static URL[] urls = new URL[1];
  54     public static byte      byteValue = 89;
  55     public static char      charValue = 'x';
  56     public static double    doubleValue = 2.2;
  57     public static float     floatValue = 3.3f;
  58     public static int       intValue = 1;
  59     public static short     shortValue = 8;
  60     public static boolean   booleanValue = false;
  61 
  62     public static Class       classValue = Object.class;
  63     public static ClassLoader classLoaderValue;
  64     {
  65         try {
  66             urls[0] = new URL("hi there");
  67         } catch (java.net.MalformedURLException ee) {
  68         }
  69         classLoaderValue = new URLClassLoader(urls);
  70     }
  71 
  72     public static Thread      threadValue;
  73     public static ThreadGroup threadGroupValue;
  74     public static String      stringValue = "abc";
  75     public static int[]       intArrayValue = new int[] {1, 2, 3};
  76 
  77     public static $classname  objectValue = 
  78         new $classname();
  79     public String ivar = stringValue;
  80 
  81     // These are the instance methods
  82     public byte i_bytef()            { return byteValue; }
  83     public char i_charf()            { return charValue; }
  84     public double i_doublef()        { return doubleValue; }
  85     public float i_floatf()          { return floatValue; }
  86     public int i_intf()              { return intValue; }
  87     public short i_shortf()          { return shortValue; }
  88     public boolean i_booleanf()      { return booleanValue; }
  89     public String i_stringf()        { return stringValue; }
  90     public Class i_classf()          { return classValue; }
  91     public ClassLoader i_classLoaderf()
  92                                      { return classLoaderValue; }
  93     public Thread i_threadf()        { return threadValue = Thread.currentThread(); }
  94     public ThreadGroup i_threadGroupf()  
  95                                      { return threadGroupValue = threadValue.getThreadGroup(); }
  96     public int[] i_intArrayf()       { return intArrayValue; }
  97     public Object i_nullObjectf()    { return null; }
  98     public Object i_objectf()        { return objectValue; }
  99     public void i_voidf()            {}
 100 
 101     static void doit($classname xx) {
 102 
 103         xx.i_bytef();
 104         xx.i_charf();
 105         xx.i_doublef();
 106         xx.i_floatf();
 107         xx.i_intf();
 108         xx.i_shortf();
 109         xx.i_booleanf();
 110         xx.i_stringf();
 111         xx.i_intArrayf();
 112         xx.i_classf();
 113         xx.i_classLoaderf();
 114         xx.i_threadf();
 115         xx.i_threadGroupf();
 116         xx.i_nullObjectf();
 117         xx.i_objectf();
 118         xx.i_voidf();
 119 
 120         // Prove it works for native methods too
 121         StrictMath.sin(doubleValue);
 122         stringValue.intern();
 123     }
 124 
 125     public static void bkpt() {
 126        int i = 0;     //@1 breakpoint
 127     }
 128 
 129     public static String traceMethods() {
 130         return "traceMethods";
 131     }
 132 
 133     public static String traceMethods1() {
 134         return "traceMethods1";
 135     }
 136 
 137     public static String traceExits() {
 138         return "traceExits";
 139     }
 140 
 141     public static String traceExits1() {
 142         return "traceExits1";
 143     }
 144 
 145     public static String traceExit() {
 146         return "traceExit";
 147     }
 148 
 149     public static String traceExit1() {
 150         return "traceExit1";
 151     }
 152 
 153     public static void main(String[] args) {
 154         // The debugger will stop at the start of main,
 155         // enable method exit events, and then do
 156         // a resume.
 157 
 158         $classname xx = new $classname();
 159         System.out.println("threadid="+Thread.currentThread().getId());
 160         bkpt();
 161 
 162         // test all possible return types
 163         doit(xx);
 164         bkpt();
 165         
 166        // test trace methods
 167        traceMethods();
 168 
 169        // test trace go methods
 170        traceMethods1();
 171        bkpt();
 172 
 173        // test trace method exits
 174        traceExits();
 175 
 176        // test trace method exits
 177        traceExits1();
 178        bkpt();
 179        
 180        // test trace method exit
 181        traceExit();
 182 
 183        // test trace method exit
 184        traceExit1();
 185        bkpt();
 186        
 187     }
 188 }
 189 EOF
 190 }
 191 
 192 
 193 # drive jdb by sending cmds to it and examining its output
 194 dojdbCmds()
 195 {
 196     setBkpts @1
 197 
 198     # test all possible return types
 199     runToBkpt @1
 200     debuggeeMatchRegexp "s/threadid=\(.*\)/\1/g"
 201     threadid=$?
 202     cmd untrace
 203 
 204     cmd trace methods
 205     cmd trace
 206     jdbFailIfNotPresent "trace methods in effect"
 207 
 208     cmd trace go methods
 209     cmd trace
 210     jdbFailIfNotPresent "trace go methods in effect"
 211 
 212     cmd trace method exits
 213     cmd trace
 214     jdbFailIfNotPresent "trace method exits in effect"
 215 
 216     cmd trace go method exits
 217     cmd trace
 218     jdbFailIfNotPresent "trace go method exits in effect"
 219 
 220     cmd trace method exit
 221     cmd trace
 222     jdbFailIfNotPresent "trace method exit in effect for JdbMethodExitTest.bkpt"
 223 
 224     cmd trace go method exit
 225     cmd trace
 226     jdbFailIfNotPresent "trace go method exit in effect for JdbMethodExitTest.bkpt"
 227 
 228 
 229     # trace exit of methods with all the return values
 230     # (but just check a couple of them)
 231     cmd trace go method exits $threadid
 232     cmd cont
 233     jdbFailIfNotPresent "instance of JdbMethodExitTest"
 234     jdbFailIfNotPresent "return value = 8"
 235 
 236     # Get out of bkpt back to the call to traceMethods
 237     cmd step up
 238 
 239 
 240     cmd trace methods $threadid
 241     cmd cont
 242     jdbFailIfNotPresent "Method entered:"
 243     cmd cont
 244     jdbFailIfNotPresent "Method exited: return value = \"traceMethods\""
 245     cmd step up
 246 
 247 
 248     cmd trace go methods $threadid
 249     cmd cont
 250     cmd cont
 251     cmd cont
 252     jdbFailIfNotPresent "Method entered: \"thread=main\", JdbMethodExitTest.traceMethods1"
 253     jdbFailIfNotPresent 'Method exited: .* JdbMethodExitTest.traceMethods1'
 254     cmd untrace
 255     cmd step up
 256 
 257 
 258     cmd trace method exits $threadid
 259     cmd cont
 260     jdbFailIfNotPresent "Method exited: return value = \"traceExits\""
 261     cmd untrace
 262     cmd step up
 263 
 264 
 265     cmd trace go method exits $threadid
 266     cmd cont
 267     jdbFailIfNotPresent 'Method exited: .* JdbMethodExitTest.traceExits1'
 268     cmd untrace
 269     cmd step up
 270 
 271 
 272     cmd step            # step into traceExit()
 273     cmd trace method exit $threadid
 274     cmd cont
 275     jdbFailIfNotPresent "Method exited: return value = \"traceExit\""
 276     cmd untrace
 277     cmd step up
 278 
 279 
 280     cmd step
 281     cmd step           # skip over setting return value in caller :-(
 282     cmd trace go method exit $threadid
 283     cmd cont
 284     jdbFailIfNotPresent 'Method exited: .*JdbMethodExitTest.traceExit1'
 285 }
 286 
 287 
 288 mysetup()
 289 {
 290     if [ -z "$TESTSRC" ] ; then
 291         TESTSRC=.
 292     fi
 293 
 294     for ii in . $TESTSRC $TESTSRC/.. ; do
 295         if [ -r "$ii/ShellScaffold.sh" ] ; then
 296             . $ii/ShellScaffold.sh 
 297             break
 298         fi
 299     done
 300 }
 301 
 302 # You could replace this next line with the contents
 303 # of ShellScaffold.sh and this script will run just the same.
 304 mysetup
 305 
 306 runit
 307 jdbFailIfNotPresent "Breakpoint hit"
 308 pass