--- old/test/jdk/com/sun/jdi/ShellScaffold.sh 2018-10-03 17:44:23.812233000 -0700 +++ /dev/null 2018-10-03 17:44:24.000000000 -0700 @@ -1,1221 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2002, 2017, 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. -# - -# -# -# jtreg runs this in a scratch dir. -# It (and runregress -no) sets these env vars: -# TESTSRC: The dir that contains this file -# TESTCLASSES: Where .class files are compiled to -# TESTJAVA: The jdk to run -# -# This is a 'library' script that is included by -# shell script test cases that want to run a .java file as the debuggee -# and use jdb as the debugger. This file contains -# several functions that support such a test. - -# The caller script can also set these shell vars before -# including this file: -# pkg= To use a package, define it here and put -# package $pkg -# in your java file -# classname= Omit this to use the default class name, 'shtest'. - -# compileOptions= compile options for at least the first compile, -# eg, compileOptions=-g -# compileOptions2= Options for the 2nd, ..., compile. compileOptions1 -# is used if this is not set. To use no compile -# options for the 2nd ... compiles, do -# compileOptions2=none -# -# mode=-Xcomp or mode=-Xint to run in these modes. These should not -# really be used since the tests are normally -# run in both modes. -# javacCmd=path-to-javac to use a non-standard javac for compiling -# compileOptions= Options to pass to javac -# -# See RedefineException.sh as an example of a caller script. -# -# To do RedefineClasses operations, embed @1 tags in the .java -# file to tell this script how to modify it to produce the 2nd -# version of the .class file to be used in the redefine operation. -# Here are examples of each editting tag and what change -# it causes in the new file. Note that blanks are not preserved -# in these editing operations. -# -# @1 uncomment -# orig: // @1 uncomment gus = 89; -# new: gus = 89; -# -# @1 commentout -# orig: gus = 89 // @1 commentout -# new: // gus = 89 // @1 commentout -# -# @1 delete -# orig: gus = 89 // @1 delete -# new: entire line deleted -# -# @1 newline -# orig: gus = 89; // @1 newline gus++; -# new: gus = 89; // -# gus++; -# -# @1 replace -# orig: gus = 89; // @1 replace gus = 90; -# new: gus = 90; -# -# The only other tag supported is @1 breakpoint. The setbkpts function -# sets bkpts at all lines that contain this string. -# -# Currently, all these tags are start with @1. It is envisioned that this script -# could be ehanced to allow multiple cycles of redefines by allowing -# @2, @3, ... tags. IE, processing the @i tags in the ith version of -# the file will produce the i+1th version of the file. -# -# There are problem with jtreg leaving behind orphan java and jdb processes -# when this script is run. Sometimes, on some platforms, it just doesn't -# get them all killed properly. -# The solution is to put a magic word in the cmd lines of background java -# and jdb processes this script launches. We can then do the right kind -# of ps cmds to find all these processes and kill them. We do this by -# trapping the completion of this script. -# -# An associated problem is that our trap handler (cleanup) doesn't -# always get called when jtreg terminates a test. This can leave tests -# hanging but following tests should run ok because each test uses -# unique names for the port and temp files (based on the PID returned -# by $$). -# -# mks 6.2a on win 98 presents two problems: -# $! returns the PID as a negative number whereas ps returns -# it in the form 0xFFF.... This means our trick of -# of using $! to get the PIDs of the jdb and debuggee processes -# doesn't work. This will cause some error cases to fail -# with a jtreg timeout instead of failing more gracefully. -# -# There is no form of the ps command that will show the whole -# cmd line. Thus, the magic keyword trick doesn't work. We -# resort to just killing java.exe and jdb.exes -# -# pid usage: -# debuggeepid: used in jdb process to detect if debuggee has died. -# - waitForDebuggeeMsg: fail if debuggee is gone -# -# jdbpid: dofail: used to detect if in main process or jdb process -# waitforfinish: quit if the jdb process is gone - -#killcmd=/bin/kill -killcmd=kill - -# This can be increased if timing seems to be an issue. -sleep_seconds=1 -timeout_factor=1 -if [ -n "$TESTTIMEOUTFACTOR" ] ; then - # convert float value to int - timeout_factor=$(echo $TESTTIMEOUTFACTOR | awk '{printf "%d\n", int($1)}') -fi - -echo "ShellScaffold.sh: Running with timeout_factor = $timeout_factor" >& 2 -topPid=$$ - -# Be careful to echo to >& in these general functions. -# If they are called from the functions that are sending -# cmds to jdb, then stdout is redirected to jdb. -cleanup() -{ - if [ -r "$failFile" ] ; then - ls -l "$failFile" >&2 - echo "" >&2 - cat "$failFile" >&2 - echo "" >&2 - fi - - # Kill all processes that have our special - # keyword in their cmd line. - killOrphans cleanup $jdbKeyword - killOrphans cleanup $debuggeeKeyword -} - -# Kill all processes with $2 in their cmd lines -# Print a msg about this using $1 as the prefix -killOrphans() -{ - str=$2 - - if [ -z "$isCygwin" ] ; then - toBeKilled=`$psCmd | $grep -v grep | $grep -i $str | awk '{print $1}' | tr '\n\r' ' '` - else - # The cygwin ps command doesn't show the options passed to a cmd. - # We will use jps to get the win PID of the command, and - # then use ps to find the cygwin pid to be killed. - # The form of a ps output line is - # ^ ddddd dddd dddd dddd.* - # where the 4th digits are the win pid and the first - # are the cygwin pid. - if [ -r "$jdk/bin/$jstack" ] ; then - winPid=`$jdk/bin/jps -v | $grep -i $str | sed -e 's@ .*@@'` - if [ ! -z "$winPid" ] ; then - # Here is a way to kill using a win cmd and the win PID. - #echo "$1: taskkill /F $winPid" >& 2 - #taskkill /F /PID $winPid - - toBeKilled=`$psCmd | $grep -v grep | \ - $grep '^ +[0-9]+ +[0-9]+ +[0-9]+ +'"$winPid" |\ - awk '{print $1}' | tr '\n\r' ' '` - fi - else - # Well, too bad - we can't find what to kill. - toBeKilled= - fi - fi - - if [ ! -z "$toBeKilled" ] ; then - echo "$1: kill -9 $toBeKilled" >& 2 - kill -9 $toBeKilled - fi -} - -# Returns 0 if $1 is the pid of a running process -findPid() -{ - if [ -z "$1" ] ; then - return 1 - fi - - case "$osname" in - SunOS | AIX) - $psCmd | $grep '^ *'"$1 " > $devnull 2>&1 - res=$? - ;; - Windows* | CYGWIN*) - # Don't use ps on cygwin since it sometimes misses - # some processes (!). - tasklist /NH | $grep " $1 " > $devnull 2>&1 - res=$? - ;; - *) - # Never use plain 'ps', which requires a "controlling terminal" - # and will fail with a "ps: no controlling terminal" error. - # Running under 'rsh' will cause this ps error. - $psCmd -e | $grep '^ *'"$1 " > $devnull 2>&1 - res=$? - ;; - esac - return $res -} - -setup() -{ - failed= - # This is used to tag each java and jdb cmd we issue so - # we can kill them at the end of the run. - - orphanKeyword=HANGINGJAVA-$$ - debuggeeKeyword=${orphanKeyword}_DEB - jdbKeyword=${orphanKeyword}_JDB - baseArgs=-D${debuggeeKeyword} - if [ -z "$TESTCLASSES" ] ; then - echo "--Warning: TESTCLASSES is not defined; using TESTCLASSES=." - echo " You should run: " - echo " runregress $0 -no" - echo " or" - echo " (setenv TESTCLASSES .; $0 $*)" - TESTCLASSES=. - fi - if [ ! -z "$TESTJAVA" ] ; then - jdk="$TESTJAVA" - else - echo "--Error: TESTJAVA must be defined as the pathname of a jdk to test." - exit 1 - fi - - ulimitCmd= - osname=`uname -s` - isCygwin= - case "$osname" in - Windows* | CYGWIN*) - devnull=NUL - case "$osname" in - CYGWIN*) - isCygwin=1 - devnull=/dev/null - ;; - esac - - if [ -r $jdk/bin/dt_shmem.dll ] ; then - transport=dt_shmem - address=kkkk.$$ - else - transport=dt_socket - address= - fi - baseArgs="$baseArgs -XX:-ShowMessageBoxOnError" - # jtreg puts \\s in TESTCLASSES and some uses, eg. echo - # treat them as control chars on mks (eg \t is tab) - # Oops; windows mks really seems to want this cat line - # to start in column 1 - if [ -w "$Temp" ] ; then - tmpFile=$Temp/tmp.$$ - elif [ -w "$TEMP" ] ; then - tmpFile=$TEMP/tmp.$$ - else - tmpFile=tmp.$$ - fi -cat <$tmpFile -$TESTCLASSES -EOF - TESTCLASSES=`cat $tmpFile | sed -e 's@\\\\@/@g'` - rm -f $tmpFile - # on mks - grep=egrep - psCmd=ps - jstack=jstack.exe - ;; - SunOS | Linux | Darwin | AIX) - transport=dt_socket - address= - devnull=/dev/null - grep=egrep - jstack=jstack - # On linux, core files take a long time, and can leave - # zombie processes - if [ "$osname" = SunOS ] ; then - # Experiments show Solaris '/usr/ucb/ps -axwww' and - # '/usr/bin/pgrep -f -l' provide the same small amount of the - # argv string (PRARGSZ=80 in /usr/include/sys/procfs.h) - # 1) This seems to have been working OK in ShellScaffold. - # 2) OpenSolaris does not provide /usr/ucb/ps, so use pgrep - # instead - # The alternative would be to use /usr/bin/pargs [pid] to get - # all the args for a process, splice them back into one - # long string, then grep. - UU=`/usr/xpg4/bin/id -u -n` - psCmd="pgrep -f -l -U $UU" - else - ulimit -c 0 - # See bug 6238593. - psCmd="ps axwww" - fi - ;; - *) - echo "--Error: Unknown result from 'uname -s': $osname" - exit 1 - ;; - esac - - - tmpFileDir=$TESTCLASSES/aa$$ - TESTCLASSES=$tmpFileDir - - mkdir -p $tmpFileDir - - # This must not contain 'jdb' or it shows up - # in grep of ps output for some platforms - jdbOutFile=$tmpFileDir/jxdbOutput.txt - rm -f $jdbOutFile - touch $jdbOutFile - - debuggeeOutFile=$tmpFileDir/debuggeeOutput.txt - failFile=$tmpFileDir/testFailed - debuggeepidFile=$tmpFileDir/debuggeepid - rm -f $failFile $debuggeepidFile - if [ -f "$failFile" ]; then - echo "ERROR: unable to delete existing failFile:" >&2 - ls -l "$failFile" >&2 - fi - - if [ -z "$pkg" ] ; then - pkgSlash= - pkgDot= - redefineSubdir=. - else - pkgSlash=$pkg/ - pkgDot=$pkg. - redefineSubdir=$pkgSlash - fi - if [ -z "$classname" ] ; then - classname=shtest - fi - - if [ -z "$java" ] ; then - java=java - fi - - if [ -z "$jdb" ] ; then - jdb=$jdk/bin/jdb - fi - -####################################################3 -####################################################3 -####################################################3 -####################################################3 -# sol: this gets all processes killed but -# no jstack -# linux same as above -# win mks: No dice; processes still running - trap "cleanup" 0 1 2 3 4 6 9 10 15 - - jdbOptions="$jdbOptions -J-D${jdbKeyword}" -} - -docompile() -{ - if [ "$compile" = 0 ] ; then - return - fi - saveDir=`pwd` - cd $tmpFileDir - rm -f *.java - createJavaFile $classname - - # Compile two versions of the file, the original and with the - # indicated lines modified. - cp $classname.java.1 $classname.java - echo "--Compiling first version of `pwd`/$classname.java with options: $compileOptions" - # Result is in $pkgSlash$classname.class - - if [ -z "$javacCmd" ] ; then - javacCmd=$jdk/bin/javac - fi - - echo "compiling " `ls *.java` - $javacCmd $compileOptions -d . *.java - if [ $? != 0 ] ; then - dofail "First compile failed" - fi - if [ -r vers1 ] ; then - rm -rf vers1 - fi - mkdir -p vers1 - mv *.class vers1 - if [ ! -z "$compileOptions2" ] ; then - if [ "$compileOptions2" = none ] ; then - compileOptions= - else - compileOptions=$compileOptions2 - fi - fi - - while [ 1 = 1 ] ; do - # Not really a loop; just a way to avoid goto - # by using breaks - sed -e '/@1 *delete/ d' \ - -e 's! *// *@1 *uncomment! !' \ - -e 's!\(.*@1 *commentout\)!//\1!' \ - -e 's/@1 *newline/\ - /' \ - -e 's/.*@1 *replace//' \ - $classname.java.1 >$classname.java - - cmp -s $classname.java.1 $classname.java - if [ $? = 0 ] ; then - break - fi - echo - echo "--Compiling second version of `pwd`/$classname.java with $compileOptions" - $javacCmd $compileOptions -d . $classname.java - if [ $? != 0 ] ; then - dofail "Second compile failed" - fi - if [ -r vers2 ] ; then - rm -rf vers2 - fi - mkdir -p vers2 - mv *.class vers2 - mv $classname.java $classname.java.2 - cp $classname.java.1 $classname.java - - ###### Do the same for @2, and @3 allowing 3 redefines to occur. - ###### If I had more time to write sed cmds, I would do - ###### this in a loop. But, I don't think we will ever need - ###### more than 3 redefines. - sed -e '/@2 *delete/ d' \ - -e 's! *// *@2 *uncomment! !' \ - -e 's!\(.*@2 *commentout\)!//\1!' \ - -e 's/@2 *newline/\ - /' \ - -e 's/.*@2 *replace//' \ - $classname.java.2 >$classname.java - cmp -s $classname.java.2 $classname.java - if [ $? = 0 ] ; then - break - fi - echo - echo "--Compiling third version of `pwd`/$classname.java with $compileOptions" - $javacCmd $compileOptions -d . $classname.java - if [ $? != 0 ] ; then - dofail "Third compile failed" - fi - if [ -r vers3 ] ; then - rm -rf vers3 - fi - mkdir -p vers3 - mv *.class vers3 - mv $classname.java $classname.java.3 - cp $classname.java.1 $classname.java - - ######## - sed -e '/@3 *delete/ d' \ - -e 's! *// *@3 *uncomment! !' \ - -e 's!\(.*@3 *commentout\)!//\1!' \ - -e 's/@3 *newline/\ - /' \ - -e 's/.*@3 *replace//' \ - $classname.java.3 >$classname.java - cmp -s $classname.java.3 $classname.java - if [ $? = 0 ] ; then - break - fi - echo - echo "--Compiling fourth version of `pwd`/$classname.java with $compileOptions" - $javacCmd $compileOptions -d . $classname.java - if [ $? != 0 ] ; then - dofail "fourth compile failed" - fi - if [ -r vers4 ] ; then - rm -rf vers4 - fi - mkdir -p vers4 - mv *.class vers4 - mv $classname.java $classname.java.4 - cp $classname.java.1 $classname.java - break - fgrep @4 $classname.java - if [ $? = 0 ] ; then - echo "--Error: @4 and above are not yet allowed" - exit 1 - fi - done - - cp vers1/* $redefineSubdir - cd $saveDir -} - -# Send a cmd to jdb and wait for the jdb prompt to appear. -# We don't want to allow > as a prompt because if the debuggee -# runs for awhile after a command, jdb will show this prompt -# but is not really ready to accept another command for the -# debuggee - ie, a cont in this state will be ignored. -# If it ever becomes necessary to send a jdb command before -# a main[10] form of prompt appears, then this -# code will have to be modified. -# -# Specify $1 = allowExit to show that the command given -# allows JDB to exit -cmd() -{ - allowExit= - case "$1" in - allowExit) - allowExit="allowExit" - shift - ;; - exitJdb) - # Quit JDB only with this cmd() invocation - echo "--Sending cmd: quit" >& 2 - echo quit - echo "--Quit cmd was sent" >& 2 - # See 6562090. Maybe there is a way that the exit - # can cause jdb to not get the quit. - sleep 5 - - # The exit code value here doesn't matter since this function - # is called as part of a pipeline and it is not the last command - # in the pipeline. - exit 1 - ;; - esac - command=$* - - if [ -z "$command" ] ; then - dofail "Command can't be a null string. Test failure" - fi - if [ "$command" = "quit" -o "$command" = "exit" ] ; then - # We don't want the test to manually quit jdb, - # we will do it in the end automatically - dofail "It's not allowed to send quit or exit commands from the test" - fi - if [ -r "$failFile" ] ; then - # failFile exists, it's better to finish execution - dofinish "quit" - fi - - # $jdbOutFile always exists here and is non empty - # because after starting jdb, we waited - # for the prompt. - fileSize=`wc -c $jdbOutFile | awk '{ print $1 }'` - echo "--Sending cmd: " $command >&2 - - # jjh: We have a few intermittent failures here. - # It is as if every so often, jdb doesn't - # get the first cmd that is sent to it here. - # (actually, I have seen it get the first cmd ok, - # but then not get some subsequent cmd). - # It seems like jdb really doesn't get the cmd; jdb's response - # does not appear in the jxdboutput file. It contains: - # main[1] - # The application has been disconnected - - # Is it possible - # that jdb got the cmd ok, but its response didn't make - # it to the jxdboutput file? If so, why did 'The application - # has been disconnected' make it? - - # This causes the following loop to timeout and the test to fail. - # The above echo works because the cmd (stop at ...) - # is in the System.err shown in the .jtr file. - # Also, the cmd is shown in the 'jdb never responded ...' - # msg output below after the timeout. - # And, we know jdb is started because the main[1] output is in the .jtr - # file. And, we wouldn't have gotten here if mydojdbcmds hadn't - # seen the ]. - echo $command - - # Now we have to wait for the next jdb prompt. We wait for a pattern - # to appear in the last line of jdb output. Normally, the prompt is - # - # 1) ^main[89] @ - # - # where ^ means start of line, and @ means end of file with no end of line - # and 89 is the current command counter. But we have complications e.g., - # the following jdb output can appear: - # - # 2) a[89] = 10 - # - # The above form is an array assignment and not a prompt. - # - # 3) ^main[89] main[89] ... - # - # This occurs if the next cmd is one that causes no jdb output, e.g., - # 'trace methods'. - # - # 4) ^main[89] [main[89]] .... > @ - # - # jdb prints a > as a prompt after something like a cont. - # Thus, even though the above is the last 'line' in the file, it - # isn't the next prompt we are waiting for after the cont completes. - # HOWEVER, sometimes we see this for a cont command: - # - # ^main[89] $ - # - # - # 5) ^main[89] > @ - # - # i.e., the > prompt comes out AFTER the prompt we we need to wait for. - # - # So, how do we know when the next prompt has appeared?? - # 1. Search for - # main[89] $ - # This will handle cases 1, 2, 3 - # 2. This leaves cases 4 and 5. - # - # What if we wait for 4 more chars to appear and then search for - # - # main[89] [>]$ - # - # on the last line? - # - # a. if we are currently at - # - # ^main[89] main[89] @ - # - # and a 'trace methods comes in, we will wait until at least - # - # ^main[89] main[89] main@ - # - # and then the search will find the new prompt when it completes. - # - # b. if we are currently at - # - # ^main[89] main[89] @ - # - # and the first form of cont comes in, then we will see - # - # ^main[89] main[89] > $ - # ^x@ - # - # where x is the first char of the msg output when the bkpt is hit - # and we will start our search, which will find the prompt - # when it comes out after the bkpt output, with or without the - # trailing > - # - - # wait for 4 new chars to appear in the jdb output - count=0 - desiredFileSize=`expr $fileSize + 4` - msg1=`echo At start: cmd/size/waiting : $command / $fileSize / \`date\`` - timeLimit=`expr 60 * $timeout_factor` - while [ 1 = 1 ] ; do - newFileSize=`wc -c $jdbOutFile | awk '{ print $1 } '` - #echo jj: desired = $desiredFileSize, new = $newFileSize >& 2 - - done=`expr $newFileSize \>= $desiredFileSize` - if [ $done = 1 ] ; then - break - fi - sleep ${sleep_seconds} - count=`expr $count + ${sleep_seconds}` - if [ $count -gt $timeLimit ] ; then - # record some debug info. - echo "--DEBUG: jdb $$ didn't respond to command in $count secs: $command" >& 2 - echo "--DEBUG:" $msg1 >& 2 - echo "--DEBUG: "done size/waiting : / $newFileSize / `date` >& 2 - echo "-- $jdbOutFile follows-------------------------------" >& 2 - cat $jdbOutFile >& 2 - echo "------------------------------------------" >& 2 - dojstack - dofail "jdb never responded to command: $command" - fi - done - # Note that this assumes just these chars in thread names. - waitForJdbMsg '[a-zA-Z0-9_-][a-zA-Z0-9_-]*\[[1-9][0-9]*\] [ >]*$' 1 $allowExit -} - -setBkpts() -{ - # Can set multiple bkpts, but only in one class. - # $1 is the bkpt name, eg, @1 - allLines=`$grep -n "$1 *breakpoint" $tmpFileDir/$classname.java.1 | sed -e 's@^\([0-9]*\).*@\1@g'` - for ii in $allLines ; do - cmd "stop at $pkgDot$classname:$ii" - done -} - -runToBkpt() -{ - # Don't pass allowExit here as we don't want JDB to unexpectedly exit - cmd run - # Don't need to do this - the above waits for the next prompt which comes out - # AFTER the Breakpoint hit message. - # Wait for jdb to hit the bkpt - #waitForJdbMsg "Breakpoint hit" 5 -} - -contToBkpt() -{ - # Don't pass allowExit here as we don't want JDB to unexpectedly exit - cmd cont - # Don't need to do this - the above waits for the next prompt which comes out - # AFTER the Breakpoint hit message. - # Wait for jdb to hit the bkpt - #waitForJdbMsg "Breakpoint hit" 5 -} - - -# Wait until string $1 appears in the output file, within the last $2 lines -# If $3 is allowExit, then don't fail if jdb exits before -# the desired string appears. -waitForJdbMsg() -{ - # This can be called from the jdb thread which doesn't - # have access to $debuggeepid, so we have to read it from the file. - nlines=$2 - allowExit="$3" - myCount=0 - timeLimit=`expr 40 * $timeout_factor` # wait a max of this many secs for a response from a jdb command - - while [ 1 = 1 ] ; do - if [ -r $jdbOutFile ] ; then - # Something here causes jdb to complain about Unrecognized cmd on x86. - tail -$nlines $jdbOutFile | $grep -s "$1" > $devnull 2>&1 - if [ $? = 0 ] ; then - # Found desired string - break - fi - fi - tail -2 $jdbOutFile | $grep -s "The application exited" > $devnull 2>&1 - if [ $? = 0 ] ; then - # Found 'The application exited' - echo "--JDB finished: The application exited" >&2 - if [ ! -z "$allowExit" ] ; then - # Exit is allowed - dofinish - fi - # Otherwise, it is an error if we don't find $1 - if [ -r $jdbOutFile ] ; then - tail -$nlines $jdbOutFile | $grep -s "$1" > $devnull 2>&1 - if [ $? = 0 ] ; then - break - fi - fi - dofail "JDB unexpectedly finished: Waited for jdb msg $1, but it never appeared" - fi - - sleep ${sleep_seconds} - findPid $topPid - if [ $? != 0 ] ; then - echo "--Top process ($topPid) is dead. We better die too" >&2 - dojstack - exit 1 - fi - - myCount=`expr $myCount + ${sleep_seconds}` - if [ $myCount -gt $timeLimit ] ; then - echo "--Fail: waitForJdbMsg timed out after $timeLimit seconds, looking for /$1/, in $nlines lines; exiting" >> $failFile - echo "vv jdbOutFile vvvvvvvvvvvvvvvvvvvvvvvvvvvv" >& 2 - cat $jdbOutFile >& 2 - echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" >& 2 - dojstack - exit 1 - fi - done - -} - -# Finishes JDB execution -# Specify command to finish if it's needed -dofinish() -{ - if [ ! -z "$*" ] ; then - echo "--Finish execution with sending \"$*\" command to JDB" >&2 - cmd "exitJdb" "$*" - else - echo "--Finish without sending \"quit\" command to JDB" >&2 - fi - exit 0 -} - -# $1 is the string to print. If $2 exists, -# it is the name of a file to print, ie, the name -# of the file that contains the $1 string. -dofail() -{ - if [ ! -z "$jdbpid" ] ; then - # we are in the main process instead of the jdb process - echo " " >> $failFile - echo "--Fail: main: $*" >> $failFile - else - # Kill the debuggee ; it could be hung so - # we want to get rid of it as soon as possible. - killOrphans "killing debuggee" $debuggeeKeyword - # Kill debugger, it could be hung - killOrphans "killing debugger" $jdbKeyword - - echo " " >>$failFile - echo "--Fail: $*" >> $failFile - fi - if [ ! -z "$2" ] ; then - echo "---- contents of $2 follows -------" >> $failFile - cat "$2" >> $failFile - echo "---------------" >>$failFile - fi - exit 1 -} - - -redefineClass() -{ - if [ -z "$1" ] ; then - vers=2 - else - vers=`echo $1 | sed -e 's/@//'` - vers=`expr $vers + 1` - fi - - cmd "redefine $pkgDot$classname $tmpFileDir/vers$vers/$classname.class" - - cp $tmpFileDir/$classname.java.$vers \ - $tmpFileDir/$classname.java -} - -mydojdbCmds() -{ - # Wait for jdb to start before we start sending cmds - waitForJdbMsg ']' 1 - # Send commands from the test - dojdbCmds - # Finish jdb with quit command - dofinish "quit" -} - -startJdb() -{ - if [ ! -r "$jdb" -a ! -r "$jdb.exe" ] ; then - dofail "$jdb does not exist" - fi - echo - echo "--Starting jdb, address=$address" - if [ -z "$address" ] ; then - # Let jdb choose the port and write it to stdout - mydojdbCmds | $jdb $jdbOptions -listenany | tee $jdbOutFile & - - while [ 1 ] ; do - lastLine=`$grep 'Listening at address' $jdbOutFile` - if [ ! -z "$lastLine" ] ; then - break - fi - sleep 1 - done - # jjh: we got the address ok, and seemed to start the debuggee - address=`echo $lastLine | sed -e 's@.*: *@@'` - else - mydojdbCmds | $jdb $jdbOptions -listen $address | tee $jdbOutFile & - fi - #echo address = $address - - - # this gets the pid of tee, at least it does on solaris - jdbpid=$! - - # This fails on linux because there is an entry for each thread in jdb - # so we get a list of numbers in jdbpid - # jdbpid=`$psCmd | $grep -v grep | $grep ${orphanKeyword}_JDB | awk '{print $1}' | tr '\n\r' ' '` -} - -startDebuggee() -{ - args="$TESTVMOPTS $TESTJAVAOPTS" - - if [ ! -z "$args" ] ; then - echo "--Starting debuggee with args from TESTVMOPTS and/or TESTJAVAOPTS: $args" - else - echo "--Starting debuggee" - fi - - debuggeepid= - waitForJdbMsg Listening 4 - - beOption="-agentlib:jdwp=transport=$transport,address=$address,server=n,suspend=y" -# beOption="-Xdebug -Xrunjdwp:transport=$transport,address=$address,server=n,suspend=y" - - thecmd="$jdk/bin/$java $mode -classpath $tmpFileDir $baseArgs $args \ - -Djtreg.classDir=$TESTCLASSES \ - -showversion \ - $beOption \ - $pkgDot$classname" - echo "Cmd: $thecmd" - - sh -c "$thecmd | tee $debuggeeOutFile" & - - # Note that the java cmd and the tee cmd will be children of - # the sh process. We can use that to find them to kill them. - debuggeepid=$! - - # Save this in a place where the jdb process can find it. - # Note that it is possible for the java cmd to abort during startup - # due to a bad classpath or whatever. - echo $debuggeepid > $debuggeepidFile -} - -dojstack() -{ - if [ -r "$jdk/bin/$jstack" ] ; then - # If jstack exists, so will jps - # Show stack traces of jdb and debuggee as a possible debugging aid. - jdbCmd=`$jdk/bin/jps -v | $grep $jdbKeyword` - realJdbPid=`echo "$jdbCmd" | sed -e 's@ .*@@'` - if [ ! -z "$realJdbPid" ] ; then - echo "-- jdb process info ----------------------" >&2 - echo " $jdbCmd" >&2 - echo "-- jdb threads: jstack $realJdbPid" >&2 - $jdk/bin/$jstack $realJdbPid >&2 - echo "------------------------------------------" >&2 - echo >&2 - fi - debuggeeCmd=`$jdk/bin/jps -v | $grep $debuggeeKeyword` - realDebuggeePid=`echo "$debuggeeCmd" | sed -e 's@ .*@@'` - if [ ! -z "$realDebuggeePid" ] ; then - echo "-- debuggee process info ----------------------" >&2 - echo " $debuggeeCmd" >&2 - echo "-- debuggee threads: jstack $moption $realDebuggeePid" >&2 - $jdk/bin/$jstack $realDebuggeePid >&2 - echo "=============================================" >&2 - echo >&2 - fi - fi -} - -waitForFinish() -{ - # This is the main process - # Wait for the jdb process to finish, or some error to occur - - while [ 1 = 1 ] ; do - findPid $jdbpid - if [ $? != 0 ] ; then - break - fi - - # (Don't use jdbFailIfPresent here since it is not safe - # to call from different processes) - $grep -s 'Input stream closed' $jdbOutFile > $devnull 2>&1 - if [ $? = 0 ] ; then - dofail "jdb input stream closed prematurely" - fi - - # If a failure has occured, quit - if [ -r "$failFile" ] ; then - break - fi - - sleep ${sleep_seconds} - done - - # jdb exited because its input stream closed prematurely - # (Don't use jdbFailIfPresent here since it is not safe - # to call from different processes) - $grep -s 'Input stream closed' $jdbOutFile > $devnull 2>&1 - if [ $? = 0 ] ; then - dofail "jdb input stream closed prematurely" - fi - - # It is necessary here to avoid the situation when JDB exited but - # mydojdbCmds() didn't finish because it waits for JDB message - # in waitForJdbMsg(), at the same time main process will finish - # the execution with no errors. - # To avoid that, wait for spawned processes to finish - case "$osname" in - SunOS) - # `wait` function doesn't work in Solaris shell as in bash, - # so create replacement that finds mydojdbCmds() shell process - # and waits for its finish - cmdsPid= - # get list of processes except main process with $topPid - processes=`$psCmd | $grep -v "$grep" | $grep -v $topPid | awk '{print $1}'` - for pid in $processes; do - # for each process grep its full args string for test name $0 - # $0 contains full test name with path - pargs -l $pid 2>$devnull | $grep "$0" >$devnull 2>&1 - if [ $? = 0 ] ; then - cmdsPid=$pid - break - fi - done - echo "--waitForFinish: Waiting for mydojdbCmds() to finish" >&2 - while [ 1 = 1 ] ; do - findPid $cmdsPid - if [ $? != 0 ] ; then - break - fi - sleep ${sleep_seconds} - done - ;; - *) - echo "--waitForFinish: Waiting for all processes to finish" >&2 - wait - ;; - esac - - if [ -r "$failFile" ] ; then - ls -l "$failFile" >&2 - echo "" >&2 - cat "$failFile" >&2 - echo "" >&2 - exit 1 - fi -} - -# $1 is the filename, $2 is the string to look for, -# $3 is the number of lines to search (from the end) -grepForString() -{ - if [ -z "$3" ] ; then - theCmd=cat - else - theCmd="tail -$3" - fi - - case "$2" in - *\>*) - # Target string contains a '>' so we better not ignore it - $theCmd $1 | $grep -s "$2" > $devnull 2>&1 - stat="$?" - ;; - *) - # Target string does not contain a '>'. - # NOTE: if $1 does not end with a new line, piping it to sed - # doesn't include the chars on the last line. Detect this - # case, and add a new line. - theFile="$1" - if [ `tail -1 "$theFile" | wc -l | sed -e 's@ @@g'` = 0 ] ; then - # The target file doesn't end with a new line so we have - # add one to a copy of the target file so the sed command - # below can filter that last line. - cp "$theFile" "$theFile.tmp" - theFile="$theFile.tmp" - echo >> "$theFile" - fi - - # See bug 6220903. Sometimes the jdb prompt chars ('> ') can - # get interleaved in the target file which can keep us from - # matching the target string. - $theCmd "$theFile" | sed -e 's@> @@g' -e 's@>@@g' \ - | $grep -s "$2" > $devnull 2>&1 - stat=$? - if [ "$theFile" != "$1" ]; then - # remove the copy of the target file - rm -f "$theFile" - fi - unset theFile - esac - - return $stat -} - -# $1 is the filename, $2 is the regexp to match and return, -# $3 is the number of lines to search (from the end) -matchRegexp() -{ - if [ -z "$3" ] ; then - theCmd=cat - else - theCmd="tail -$3" - fi - - case "$2" in - *\>*) - # Target string contains a '>' so we better not ignore it - res=`$theCmd $1 | sed -e "$2"` - ;; - *) - # Target string does not contain a '>'. - # NOTE: if $1 does not end with a new line, piping it to sed - # doesn't include the chars on the last line. Detect this - # case, and add a new line. - theFile="$1" - if [ `tail -1 "$theFile" | wc -l | sed -e 's@ @@g'` = 0 ] ; then - # The target file doesn't end with a new line so we have - # add one to a copy of the target file so the sed command - # below can filter that last line. - cp "$theFile" "$theFile.tmp" - theFile="$theFile.tmp" - echo >> "$theFile" - fi - - # See bug 6220903. Sometimes the jdb prompt chars ('> ') can - # get interleaved in the target file which can keep us from - # matching the target string. - res=`$theCmd "$theFile" | sed -e 's@> @@g' -e 's@>@@g' \ - | sed -e "$2"` - if [ "$theFile" != "$1" ]; then - # remove the copy of the target file - rm -f "$theFile" - fi - unset theFile - esac - return $res -} - -# $1 is the filename, $2 is the string to look for, -# $3 is the number of lines to search (from the end) -failIfPresent() -{ - if [ -r "$1" ] ; then - grepForString "$1" "$2" "$3" - if [ $? = 0 ] ; then - dofail "Error output found: \"$2\" in $1" $1 - fi - fi -} - -# $1 is the filename, $2 is the string to look for -# $3 is the number of lines to search (from the end) -failIfNotPresent() -{ - if [ ! -r "$1" ] ; then - dofail "Required output \"$2\" not found in $1" - fi - grepForString "$1" "$2" "$3" - if [ $? != 0 ] ; then - dofail "Required output \"$2\" not found in $1" $1 - fi - -} - -# fail if $1 is not in the jdb output -# $2 is the number of lines to search (from the end) -jdbFailIfNotPresent() -{ - failIfNotPresent $jdbOutFile "$1" $2 -} - -# fail if $1 is not in the debuggee output -# $2 is the number of lines to search (from the end) -debuggeeFailIfNotPresent() -{ - failIfNotPresent $debuggeeOutFile "$1" $2 -} - -# fail if $1 is in the jdb output -# $2 is the number of lines to search (from the end) -jdbFailIfPresent() -{ - failIfPresent $jdbOutFile "$1" $2 -} - -# fail if $1 is in the debuggee output -# $2 is the number of lines to search (from the end) -debuggeeFailIfPresent() -{ - failIfPresent $debuggeeOutFile "$1" $2 -} - -# match and return the output from the regexp $1 in the debuggee output -# $2 is the number of lines to search (from the end) -debuggeeMatchRegexp() -{ - matchRegexp $debuggeeOutFile "$1" $2 -} - - -# This should really be named 'done' instead of pass. -pass() -{ - if [ ! -r "$failFile" ] ; then - echo - echo "--Done: test passed" - exit 0 - else - ls -l "$failFile" >&2 - echo "" >&2 - cat "$failFile" >&2 - echo "" >&2 - fi -} - -runit() -{ - setup - docompile - startJdb - startDebuggee - waitForFinish - - # in hs_err file from 1.3.1 - debuggeeFailIfPresent "Virtual Machine Error" - - # in hs_err file from 1.4.2, 1.5: An unexpected error - debuggeeFailIfPresent "An unexpected error" - - # in hs_err file from 1.4.2, 1.5: Internal error - debuggeeFailIfPresent "Internal error" - - - # Don't know how this arises - debuggeeFailIfPresent "An unexpected exception" - - # Don't know how this arises - debuggeeFailIfPresent "Internal exception" -}