#!/bin/sh
#
# Copyright (c) 2004, 2005, 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.
#
# @test
# @bug 6202891
# @summary TTY: Add support for method exit event return values to jdb
# @author Jim Holmlund
# @run shell JdbMethodExitTest.sh
# These are variables that can be set to control execution
#pkg=untitled7
classname=JdbMethodExitTest
compileOptions=-g
#java="java_g"
#set -x
createJavaFile()
{
cat <<EOF > $classname.java.1
import java.util.*;
import java.net.URLClassLoader;
import java.net.URL;
/*
* This tests the jdb trace command
*/
class $classname {
// These are the values that will be returned by the methods
static URL[] urls = new URL[1];
public static byte byteValue = 89;
public static char charValue = 'x';
public static double doubleValue = 2.2;
public static float floatValue = 3.3f;
public static int intValue = 1;
public static short shortValue = 8;
public static boolean booleanValue = false;
public static Class classValue = Object.class;
public static ClassLoader classLoaderValue;
{
try {
urls[0] = new URL("hi there");
} catch (java.net.MalformedURLException ee) {
}
classLoaderValue = new URLClassLoader(urls);
}
public static Thread threadValue;
public static ThreadGroup threadGroupValue;
public static String stringValue = "abc";
public static int[] intArrayValue = new int[] {1, 2, 3};
public static $classname objectValue =
new $classname();
public String ivar = stringValue;
// These are the instance methods
public byte i_bytef() { return byteValue; }
public char i_charf() { return charValue; }
public double i_doublef() { return doubleValue; }
public float i_floatf() { return floatValue; }
public int i_intf() { return intValue; }
public short i_shortf() { return shortValue; }
public boolean i_booleanf() { return booleanValue; }
public String i_stringf() { return stringValue; }
public Class i_classf() { return classValue; }
public ClassLoader i_classLoaderf()
{ return classLoaderValue; }
public Thread i_threadf() { return threadValue = Thread.currentThread(); }
public ThreadGroup i_threadGroupf()
{ return threadGroupValue = threadValue.getThreadGroup(); }
public int[] i_intArrayf() { return intArrayValue; }
public Object i_nullObjectf() { return null; }
public Object i_objectf() { return objectValue; }
public void i_voidf() {}
static void doit($classname xx) {
xx.i_bytef();
xx.i_charf();
xx.i_doublef();
xx.i_floatf();
xx.i_intf();
xx.i_shortf();
xx.i_booleanf();
xx.i_stringf();
xx.i_intArrayf();
xx.i_classf();
xx.i_classLoaderf();
xx.i_threadf();
xx.i_threadGroupf();
xx.i_nullObjectf();
xx.i_objectf();
xx.i_voidf();
// Prove it works for native methods too
StrictMath.sin(doubleValue);
stringValue.intern();
}
public static void bkpt() {
int i = 0; //@1 breakpoint
}
public static String traceMethods() {
return "traceMethods";
}
public static String traceMethods1() {
return "traceMethods1";
}
public static String traceExits() {
return "traceExits";
}
public static String traceExits1() {
return "traceExits1";
}
public static String traceExit() {
return "traceExit";
}
public static String traceExit1() {
return "traceExit1";
}
public static void main(String[] args) {
// The debugger will stop at the start of main,
// enable method exit events, and then do
// a resume.
$classname xx = new $classname();
bkpt();
// test all possible return types
doit(xx);
bkpt();
// test trace methods
traceMethods();
// test trace go methods
traceMethods1();
bkpt();
// test trace method exits
traceExits();
// test trace method exits
traceExits1();
bkpt();
// test trace method exit
traceExit();
// test trace method exit
traceExit1();
bkpt();
}
}
EOF
}
# drive jdb by sending cmds to it and examining its output
dojdbCmds()
{
setBkpts @1
# test all possible return types
runToBkpt @1
cmd untrace
cmd trace methods
cmd trace
jdbFailIfNotPresent "trace methods in effect"
cmd trace go methods
cmd trace
jdbFailIfNotPresent "trace go methods in effect"
cmd trace method exits
cmd trace
jdbFailIfNotPresent "trace method exits in effect"
cmd trace go method exits
cmd trace
jdbFailIfNotPresent "trace go method exits in effect"
cmd trace method exit
cmd trace
jdbFailIfNotPresent "trace method exit in effect for JdbMethodExitTest.bkpt"
cmd trace go method exit
cmd trace
jdbFailIfNotPresent "trace go method exit in effect for JdbMethodExitTest.bkpt"
# trace exit of methods with all the return values
# (but just check a couple of them)
cmd trace go exits
cmd cont
jdbFailIfNotPresent "instance of JdbMethodExitTest"
jdbFailIfNotPresent "return value = 8"
# Get out of bkpt back to the call to traceMethods
cmd step up
cmd trace methods
cmd cont
jdbFailIfNotPresent "Method entered:"
cmd cont
jdbFailIfNotPresent "Method exited: return value = \"traceMethods\""
cmd step up
cmd trace go methods
cmd cont
jdbFailIfNotPresent "Method entered: \"thread=main\", JdbMethodExitTest.traceMethods1"
jdbFailIfNotPresent 'Method exited: .* JdbMethodExitTest.traceMethods1'
cmd untrace
cmd step up
cmd trace method exits
cmd cont
jdbFailIfNotPresent "Method exited: return value = \"traceExits\""
cmd untrace
cmd step up
cmd trace go method exits
cmd cont
jdbFailIfNotPresent 'Method exited: .* JdbMethodExitTest.traceExits1'
cmd untrace
cmd step up
cmd step # step into traceExit()
cmd trace method exit
cmd cont
jdbFailIfNotPresent "Method exited: return value = \"traceExit\""
cmd untrace
cmd step up
cmd step
cmd step # skip over setting return value in caller :-(
cmd trace go method exit
cmd cont
jdbFailIfNotPresent 'Method exited: .*JdbMethodExitTest.traceExit1'
cmd quit
}
mysetup()
{
if [ -z "$TESTSRC" ] ; then
TESTSRC=.
fi
for ii in . $TESTSRC $TESTSRC/.. ; do
if [ -r "$ii/ShellScaffold.sh" ] ; then
. $ii/ShellScaffold.sh
break
fi
done
}
# You could replace this next line with the contents
# of ShellScaffold.sh and this script will run just the same.
mysetup
runit
jdbFailIfNotPresent "Breakpoint hit"
pass