ShellScaffold.sh revision 12677:a4299d47bd00
1#!/bin/sh 2 3# 4# Copyright (c) 2002, 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# 27# 28# jtreg runs this in a scratch dir. 29# It (and runregress -no) sets these env vars: 30# TESTSRC: The dir that contains this file 31# TESTCLASSES: Where .class files are compiled to 32# TESTJAVA: The jdk to run 33# 34# This is a 'library' script that is included by 35# shell script test cases that want to run a .java file as the debuggee 36# and use jdb as the debugger. This file contains 37# several functions that support such a test. 38 39# The caller script can also set these shell vars before 40# including this file: 41# pkg=<package name> To use a package, define it here and put 42# package $pkg 43# in your java file 44# classname=<classnam> Omit this to use the default class name, 'shtest'. 45 46# compileOptions=<string> compile options for at least the first compile, 47# eg, compileOptions=-g 48# compileOptions2=<string> Options for the 2nd, ..., compile. compileOptions1 49# is used if this is not set. To use no compile 50# options for the 2nd ... compiles, do 51# compileOptions2=none 52# 53# mode=-Xcomp or mode=-Xint to run in these modes. These should not 54# really be used since the tests are normally 55# run in both modes. 56# javacCmd=path-to-javac to use a non-standard javac for compiling 57# compileOptions=<string> Options to pass to javac 58# 59# See RedefineException.sh as an example of a caller script. 60# 61# To do RedefineClasses operations, embed @1 tags in the .java 62# file to tell this script how to modify it to produce the 2nd 63# version of the .class file to be used in the redefine operation. 64# Here are examples of each editting tag and what change 65# it causes in the new file. Note that blanks are not preserved 66# in these editing operations. 67# 68# @1 uncomment 69# orig: // @1 uncomment gus = 89; 70# new: gus = 89; 71# 72# @1 commentout 73# orig: gus = 89 // @1 commentout 74# new: // gus = 89 // @1 commentout 75# 76# @1 delete 77# orig: gus = 89 // @1 delete 78# new: entire line deleted 79# 80# @1 newline 81# orig: gus = 89; // @1 newline gus++; 82# new: gus = 89; // 83# gus++; 84# 85# @1 replace 86# orig: gus = 89; // @1 replace gus = 90; 87# new: gus = 90; 88# 89# The only other tag supported is @1 breakpoint. The setbkpts function 90# sets bkpts at all lines that contain this string. 91# 92# Currently, all these tags are start with @1. It is envisioned that this script 93# could be ehanced to allow multiple cycles of redefines by allowing 94# @2, @3, ... tags. IE, processing the @i tags in the ith version of 95# the file will produce the i+1th version of the file. 96# 97# There are problem with jtreg leaving behind orphan java and jdb processes 98# when this script is run. Sometimes, on some platforms, it just doesn't 99# get them all killed properly. 100# The solution is to put a magic word in the cmd lines of background java 101# and jdb processes this script launches. We can then do the right kind 102# of ps cmds to find all these processes and kill them. We do this by 103# trapping the completion of this script. 104# 105# An associated problem is that our trap handler (cleanup) doesn't 106# always get called when jtreg terminates a test. This can leave tests 107# hanging but following tests should run ok because each test uses 108# unique names for the port and temp files (based on the PID returned 109# by $$). 110# 111# mks 6.2a on win 98 presents two problems: 112# $! returns the PID as a negative number whereas ps returns 113# it in the form 0xFFF.... This means our trick of 114# of using $! to get the PIDs of the jdb and debuggee processes 115# doesn't work. This will cause some error cases to fail 116# with a jtreg timeout instead of failing more gracefully. 117# 118# There is no form of the ps command that will show the whole 119# cmd line. Thus, the magic keyword trick doesn't work. We 120# resort to just killing java.exe and jdb.exes 121# 122# pid usage: 123# debuggeepid: used in jdb process to detect if debuggee has died. 124# - waitForDebuggeeMsg: fail if debuggee is gone 125# 126# jdbpid: dofail: used to detect if in main process or jdb process 127# waitforfinish: quit if the jdb process is gone 128 129#killcmd=/bin/kill 130killcmd=kill 131 132# This can be increased if timing seems to be an issue. 133sleep_seconds=1 134 135echo "ShellScaffold.sh: Version" >& 2 136topPid=$$ 137 138# Be careful to echo to >& in these general functions. 139# If they are called from the functions that are sending 140# cmds to jdb, then stdout is redirected to jdb. 141cleanup() 142{ 143 if [ -r "$failFile" ] ; then 144 ls -l "$failFile" >&2 145 echo "<cleanup:_begin_failFile_contents>" >&2 146 cat "$failFile" >&2 147 echo "<cleanup:_end_failFile_contents>" >&2 148 fi 149 150 # Kill all processes that have our special 151 # keyword in their cmd line. 152 killOrphans cleanup $jdbKeyword 153 killOrphans cleanup $debuggeeKeyword 154} 155 156# Kill all processes with $2 in their cmd lines 157# Print a msg about this using $1 as the prefix 158killOrphans() 159{ 160 str=$2 161 162 if [ -z "$isCygwin" ] ; then 163 toBeKilled=`$psCmd | $grep -v grep | $grep -i $str | awk '{print $1}' | tr '\n\r' ' '` 164 else 165 # The cygwin ps command doesn't show the options passed to a cmd. 166 # We will use jps to get the win PID of the command, and 167 # then use ps to find the cygwin pid to be killed. 168 # The form of a ps output line is 169 # ^ ddddd dddd dddd dddd.* 170 # where the 4th digits are the win pid and the first 171 # are the cygwin pid. 172 if [ -r "$jdk/bin/$jstack" ] ; then 173 winPid=`$jdk/bin/jps -v | $grep -i $str | sed -e 's@ .*@@'` 174 if [ ! -z "$winPid" ] ; then 175 # Here is a way to kill using a win cmd and the win PID. 176 #echo "$1: taskkill /F $winPid" >& 2 177 #taskkill /F /PID $winPid 178 179 toBeKilled=`$psCmd | $grep -v grep | \ 180 $grep '^ +[0-9]+ +[0-9]+ +[0-9]+ +'"$winPid" |\ 181 awk '{print $1}' | tr '\n\r' ' '` 182 fi 183 else 184 # Well, too bad - we can't find what to kill. 185 toBeKilled= 186 fi 187 fi 188 189 if [ ! -z "$toBeKilled" ] ; then 190 echo "$1: kill -9 $toBeKilled" >& 2 191 kill -9 $toBeKilled 192 fi 193} 194 195# Returns 0 if $1 is the pid of a running process 196findPid() 197{ 198 if [ -z "$1" ] ; then 199 return 1 200 fi 201 202 case "$osname" in 203 SunOS | AIX) 204 $psCmd | $grep '^ *'"$1 " > $devnull 2>&1 205 res=$? 206 ;; 207 Windows* | CYGWIN*) 208 # Don't use ps on cygwin since it sometimes misses 209 # some processes (!). 210 tasklist /NH | $grep " $1 " > $devnull 2>&1 211 res=$? 212 ;; 213 *) 214 # Never use plain 'ps', which requires a "controlling terminal" 215 # and will fail with a "ps: no controlling terminal" error. 216 # Running under 'rsh' will cause this ps error. 217 $psCmd -e | $grep '^ *'"$1 " > $devnull 2>&1 218 res=$? 219 ;; 220 esac 221 return $res 222} 223 224setup() 225{ 226 failed= 227 # This is used to tag each java and jdb cmd we issue so 228 # we can kill them at the end of the run. 229 230 orphanKeyword=HANGINGJAVA-$$ 231 debuggeeKeyword=${orphanKeyword}_DEB 232 jdbKeyword=${orphanKeyword}_JDB 233 baseArgs=-D${debuggeeKeyword} 234 if [ -z "$TESTCLASSES" ] ; then 235 echo "--Warning: TESTCLASSES is not defined; using TESTCLASSES=." 236 echo " You should run: " 237 echo " runregress $0 -no" 238 echo " or" 239 echo " (setenv TESTCLASSES .; $0 $*)" 240 TESTCLASSES=. 241 fi 242 if [ ! -z "$TESTJAVA" ] ; then 243 jdk="$TESTJAVA" 244 else 245 echo "--Error: TESTJAVA must be defined as the pathname of a jdk to test." 246 exit 1 247 fi 248 249 ulimitCmd= 250 osname=`uname -s` 251 isCygwin= 252 case "$osname" in 253 Windows* | CYGWIN*) 254 devnull=NUL 255 case "$osname" in 256 CYGWIN*) 257 isCygwin=1 258 devnull=/dev/null 259 ;; 260 esac 261 262 if [ -r $jdk/bin/dt_shmem.dll ] ; then 263 transport=dt_shmem 264 address=kkkk.$$ 265 else 266 transport=dt_socket 267 address= 268 fi 269 baseArgs="$baseArgs -XX:-ShowMessageBoxOnError" 270 # jtreg puts \\s in TESTCLASSES and some uses, eg. echo 271 # treat them as control chars on mks (eg \t is tab) 272 # Oops; windows mks really seems to want this cat line 273 # to start in column 1 274 if [ -w "$SystemRoot" ] ; then 275 tmpFile=$SystemRoot/tmp.$$ 276 elif [ -w "$SYSTEMROOT" ] ; then 277 tmpFile=$SYSTEMROOT/tmp.$$ 278 else 279 tmpFile=tmp.$$ 280 fi 281cat <<EOF >$tmpFile 282$TESTCLASSES 283EOF 284 TESTCLASSES=`cat $tmpFile | sed -e 's@\\\\@/@g'` 285 rm -f $tmpFile 286 # on mks 287 grep=egrep 288 psCmd=ps 289 jstack=jstack.exe 290 ;; 291 SunOS | Linux | Darwin | AIX) 292 transport=dt_socket 293 address= 294 devnull=/dev/null 295 grep=egrep 296 jstack=jstack 297 # On linux, core files take a long time, and can leave 298 # zombie processes 299 if [ "$osname" = SunOS ] ; then 300 # Experiments show Solaris '/usr/ucb/ps -axwww' and 301 # '/usr/bin/pgrep -f -l' provide the same small amount of the 302 # argv string (PRARGSZ=80 in /usr/include/sys/procfs.h) 303 # 1) This seems to have been working OK in ShellScaffold. 304 # 2) OpenSolaris does not provide /usr/ucb/ps, so use pgrep 305 # instead 306 # The alternative would be to use /usr/bin/pargs [pid] to get 307 # all the args for a process, splice them back into one 308 # long string, then grep. 309 UU=`/usr/xpg4/bin/id -u -n` 310 psCmd="pgrep -f -l -U $UU" 311 else 312 ulimit -c 0 313 # See bug 6238593. 314 psCmd="ps axwww" 315 fi 316 ;; 317 *) 318 echo "--Error: Unknown result from 'uname -s': $osname" 319 exit 1 320 ;; 321 esac 322 323 324 tmpFileDir=$TESTCLASSES/aa$$ 325 TESTCLASSES=$tmpFileDir 326 327 mkdir -p $tmpFileDir 328 329 # This must not contain 'jdb' or it shows up 330 # in grep of ps output for some platforms 331 jdbOutFile=$tmpFileDir/jxdbOutput.txt 332 rm -f $jdbOutFile 333 touch $jdbOutFile 334 335 debuggeeOutFile=$tmpFileDir/debuggeeOutput.txt 336 failFile=$tmpFileDir/testFailed 337 debuggeepidFile=$tmpFileDir/debuggeepid 338 rm -f $failFile $debuggeepidFile 339 if [ -f "$failFile" ]; then 340 echo "ERROR: unable to delete existing failFile:" >&2 341 ls -l "$failFile" >&2 342 fi 343 344 if [ -z "$pkg" ] ; then 345 pkgSlash= 346 pkgDot= 347 redefineSubdir=. 348 else 349 pkgSlash=$pkg/ 350 pkgDot=$pkg. 351 redefineSubdir=$pkgSlash 352 fi 353 if [ -z "$classname" ] ; then 354 classname=shtest 355 fi 356 357 if [ -z "$java" ] ; then 358 java=java 359 fi 360 361 if [ -z "$jdb" ] ; then 362 jdb=$jdk/bin/jdb 363 fi 364 365####################################################3 366####################################################3 367####################################################3 368####################################################3 369# sol: this gets all processes killed but 370# no jstack 371# linux same as above 372# win mks: No dice; processes still running 373 trap "cleanup" 0 1 2 3 4 6 9 10 15 374 375 jdbOptions="$jdbOptions -J-D${jdbKeyword}" 376} 377 378docompile() 379{ 380 if [ "$compile" = 0 ] ; then 381 return 382 fi 383 saveDir=`pwd` 384 cd $tmpFileDir 385 rm -f *.java 386 createJavaFile $classname 387 388 # Compile two versions of the file, the original and with the 389 # indicated lines modified. 390 cp $classname.java.1 $classname.java 391 echo "--Compiling first version of `pwd`/$classname.java with options: $compileOptions" 392 # Result is in $pkgSlash$classname.class 393 394 if [ -z "$javacCmd" ] ; then 395 javacCmd=$jdk/bin/javac 396 fi 397 398 echo "compiling " `ls *.java` 399 $javacCmd $compileOptions -d . *.java 400 if [ $? != 0 ] ; then 401 dofail "First compile failed" 402 fi 403 if [ -r vers1 ] ; then 404 rm -rf vers1 405 fi 406 mkdir -p vers1 407 mv *.class vers1 408 if [ ! -z "$compileOptions2" ] ; then 409 if [ "$compileOptions2" = none ] ; then 410 compileOptions= 411 else 412 compileOptions=$compileOptions2 413 fi 414 fi 415 416 while [ 1 = 1 ] ; do 417 # Not really a loop; just a way to avoid goto 418 # by using breaks 419 sed -e '/@1 *delete/ d' \ 420 -e 's! *// *@1 *uncomment! !' \ 421 -e 's!\(.*@1 *commentout\)!//\1!' \ 422 -e 's/@1 *newline/\ 423 /' \ 424 -e 's/.*@1 *replace//' \ 425 $classname.java.1 >$classname.java 426 427 cmp -s $classname.java.1 $classname.java 428 if [ $? = 0 ] ; then 429 break 430 fi 431 echo 432 echo "--Compiling second version of `pwd`/$classname.java with $compileOptions" 433 $javacCmd $compileOptions -d . $classname.java 434 if [ $? != 0 ] ; then 435 dofail "Second compile failed" 436 fi 437 if [ -r vers2 ] ; then 438 rm -rf vers2 439 fi 440 mkdir -p vers2 441 mv *.class vers2 442 mv $classname.java $classname.java.2 443 cp $classname.java.1 $classname.java 444 445 ###### Do the same for @2, and @3 allowing 3 redefines to occur. 446 ###### If I had more time to write sed cmds, I would do 447 ###### this in a loop. But, I don't think we will ever need 448 ###### more than 3 redefines. 449 sed -e '/@2 *delete/ d' \ 450 -e 's! *// *@2 *uncomment! !' \ 451 -e 's!\(.*@2 *commentout\)!//\1!' \ 452 -e 's/@2 *newline/\ 453 /' \ 454 -e 's/.*@2 *replace//' \ 455 $classname.java.2 >$classname.java 456 cmp -s $classname.java.2 $classname.java 457 if [ $? = 0 ] ; then 458 break 459 fi 460 echo 461 echo "--Compiling third version of `pwd`/$classname.java with $compileOptions" 462 $javacCmd $compileOptions -d . $classname.java 463 if [ $? != 0 ] ; then 464 dofail "Third compile failed" 465 fi 466 if [ -r vers3 ] ; then 467 rm -rf vers3 468 fi 469 mkdir -p vers3 470 mv *.class vers3 471 mv $classname.java $classname.java.3 472 cp $classname.java.1 $classname.java 473 474 ######## 475 sed -e '/@3 *delete/ d' \ 476 -e 's! *// *@3 *uncomment! !' \ 477 -e 's!\(.*@3 *commentout\)!//\1!' \ 478 -e 's/@3 *newline/\ 479 /' \ 480 -e 's/.*@3 *replace//' \ 481 $classname.java.3 >$classname.java 482 cmp -s $classname.java.3 $classname.java 483 if [ $? = 0 ] ; then 484 break 485 fi 486 echo 487 echo "--Compiling fourth version of `pwd`/$classname.java with $compileOptions" 488 $javacCmd $compileOptions -d . $classname.java 489 if [ $? != 0 ] ; then 490 dofail "fourth compile failed" 491 fi 492 if [ -r vers4 ] ; then 493 rm -rf vers4 494 fi 495 mkdir -p vers4 496 mv *.class vers4 497 mv $classname.java $classname.java.4 498 cp $classname.java.1 $classname.java 499 break 500 fgrep @4 $classname.java 501 if [ $? = 0 ] ; then 502 echo "--Error: @4 and above are not yet allowed" 503 exit 1 504 fi 505 done 506 507 cp vers1/* $redefineSubdir 508 cd $saveDir 509} 510 511# Send a cmd to jdb and wait for the jdb prompt to appear. 512# We don't want to allow > as a prompt because if the debuggee 513# runs for awhile after a command, jdb will show this prompt 514# but is not really ready to accept another command for the 515# debuggee - ie, a cont in this state will be ignored. 516# If it ever becomes necessary to send a jdb command before 517# a main[10] form of prompt appears, then this 518# code will have to be modified. 519# 520# Specify $1 = allowExit to show that the command given 521# allows JDB to exit 522cmd() 523{ 524 allowExit= 525 case "$1" in 526 allowExit) 527 allowExit="allowExit" 528 shift 529 ;; 530 exitJdb) 531 # Quit JDB only with this cmd() invocation 532 echo "--Sending cmd: quit" >& 2 533 echo quit 534 echo "--Quit cmd was sent" >& 2 535 # See 6562090. Maybe there is a way that the exit 536 # can cause jdb to not get the quit. 537 sleep 5 538 539 # The exit code value here doesn't matter since this function 540 # is called as part of a pipeline and it is not the last command 541 # in the pipeline. 542 exit 1 543 ;; 544 esac 545 command=$* 546 547 if [ -z "$command" ] ; then 548 dofail "Command can't be a null string. Test failure" 549 fi 550 if [ "$command" = "quit" -o "$command" = "exit" ] ; then 551 # We don't want the test to manually quit jdb, 552 # we will do it in the end automatically 553 dofail "It's not allowed to send quit or exit commands from the test" 554 fi 555 if [ -r "$failFile" ] ; then 556 # failFile exists, it's better to finish execution 557 dofinish "quit" 558 fi 559 560 # $jdbOutFile always exists here and is non empty 561 # because after starting jdb, we waited 562 # for the prompt. 563 fileSize=`wc -c $jdbOutFile | awk '{ print $1 }'` 564 echo "--Sending cmd: " $command >&2 565 566 # jjh: We have a few intermittent failures here. 567 # It is as if every so often, jdb doesn't 568 # get the first cmd that is sent to it here. 569 # (actually, I have seen it get the first cmd ok, 570 # but then not get some subsequent cmd). 571 # It seems like jdb really doesn't get the cmd; jdb's response 572 # does not appear in the jxdboutput file. It contains: 573 # main[1] 574 # The application has been disconnected 575 576 # Is it possible 577 # that jdb got the cmd ok, but its response didn't make 578 # it to the jxdboutput file? If so, why did 'The application 579 # has been disconnected' make it? 580 581 # This causes the following loop to timeout and the test to fail. 582 # The above echo works because the cmd (stop at ...) 583 # is in the System.err shown in the .jtr file. 584 # Also, the cmd is shown in the 'jdb never responded ...' 585 # msg output below after the timeout. 586 # And, we know jdb is started because the main[1] output is in the .jtr 587 # file. And, we wouldn't have gotten here if mydojdbcmds hadn't 588 # seen the ]. 589 echo $command 590 591 # Now we have to wait for the next jdb prompt. We wait for a pattern 592 # to appear in the last line of jdb output. Normally, the prompt is 593 # 594 # 1) ^main[89] @ 595 # 596 # where ^ means start of line, and @ means end of file with no end of line 597 # and 89 is the current command counter. But we have complications e.g., 598 # the following jdb output can appear: 599 # 600 # 2) a[89] = 10 601 # 602 # The above form is an array assignment and not a prompt. 603 # 604 # 3) ^main[89] main[89] ... 605 # 606 # This occurs if the next cmd is one that causes no jdb output, e.g., 607 # 'trace methods'. 608 # 609 # 4) ^main[89] [main[89]] .... > @ 610 # 611 # jdb prints a > as a prompt after something like a cont. 612 # Thus, even though the above is the last 'line' in the file, it 613 # isn't the next prompt we are waiting for after the cont completes. 614 # HOWEVER, sometimes we see this for a cont command: 615 # 616 # ^main[89] $ 617 # <lines output for hitting a bkpt> 618 # 619 # 5) ^main[89] > @ 620 # 621 # i.e., the > prompt comes out AFTER the prompt we we need to wait for. 622 # 623 # So, how do we know when the next prompt has appeared?? 624 # 1. Search for 625 # main[89] $ 626 # This will handle cases 1, 2, 3 627 # 2. This leaves cases 4 and 5. 628 # 629 # What if we wait for 4 more chars to appear and then search for 630 # 631 # main[89] [>]$ 632 # 633 # on the last line? 634 # 635 # a. if we are currently at 636 # 637 # ^main[89] main[89] @ 638 # 639 # and a 'trace methods comes in, we will wait until at least 640 # 641 # ^main[89] main[89] main@ 642 # 643 # and then the search will find the new prompt when it completes. 644 # 645 # b. if we are currently at 646 # 647 # ^main[89] main[89] @ 648 # 649 # and the first form of cont comes in, then we will see 650 # 651 # ^main[89] main[89] > $ 652 # ^x@ 653 # 654 # where x is the first char of the msg output when the bkpt is hit 655 # and we will start our search, which will find the prompt 656 # when it comes out after the bkpt output, with or without the 657 # trailing > 658 # 659 660 # wait for 4 new chars to appear in the jdb output 661 count=0 662 desiredFileSize=`expr $fileSize + 4` 663 msg1=`echo At start: cmd/size/waiting : $command / $fileSize / \`date\`` 664 while [ 1 = 1 ] ; do 665 newFileSize=`wc -c $jdbOutFile | awk '{ print $1 } '` 666 #echo jj: desired = $desiredFileSize, new = $newFileSize >& 2 667 668 done=`expr $newFileSize \>= $desiredFileSize` 669 if [ $done = 1 ] ; then 670 break 671 fi 672 sleep ${sleep_seconds} 673 count=`expr $count + 1` 674 if [ $count = 30 -o $count = 60 ] ; then 675 # record some debug info. 676 echo "--DEBUG: jdb $$ didn't responded to command in $count secs: $command" >& 2 677 echo "--DEBUG:" $msg1 >& 2 678 echo "--DEBUG: "done size/waiting : / $newFileSize / `date` >& 2 679 echo "-- $jdbOutFile follows-------------------------------" >& 2 680 cat $jdbOutFile >& 2 681 echo "------------------------------------------" >& 2 682 dojstack 683 #$psCmd | sed -e '/com.sun.javatest/d' -e '/nsk/d' >& 2 684 if [ $count = 60 ] ; then 685 dofail "jdb never responded to command: $command" 686 fi 687 fi 688 done 689 # Note that this assumes just these chars in thread names. 690 waitForJdbMsg '[a-zA-Z0-9_-][a-zA-Z0-9_-]*\[[1-9][0-9]*\] [ >]*$' 1 $allowExit 691} 692 693setBkpts() 694{ 695 # Can set multiple bkpts, but only in one class. 696 # $1 is the bkpt name, eg, @1 697 allLines=`$grep -n "$1 *breakpoint" $tmpFileDir/$classname.java.1 | sed -e 's@^\([0-9]*\).*@\1@g'` 698 for ii in $allLines ; do 699 cmd "stop at $pkgDot$classname:$ii" 700 done 701} 702 703runToBkpt() 704{ 705 # Don't pass allowExit here as we don't want JDB to unexpectedly exit 706 cmd run 707 # Don't need to do this - the above waits for the next prompt which comes out 708 # AFTER the Breakpoint hit message. 709 # Wait for jdb to hit the bkpt 710 #waitForJdbMsg "Breakpoint hit" 5 711} 712 713contToBkpt() 714{ 715 # Don't pass allowExit here as we don't want JDB to unexpectedly exit 716 cmd cont 717 # Don't need to do this - the above waits for the next prompt which comes out 718 # AFTER the Breakpoint hit message. 719 # Wait for jdb to hit the bkpt 720 #waitForJdbMsg "Breakpoint hit" 5 721} 722 723 724# Wait until string $1 appears in the output file, within the last $2 lines 725# If $3 is allowExit, then don't fail if jdb exits before 726# the desired string appears. 727waitForJdbMsg() 728{ 729 # This can be called from the jdb thread which doesn't 730 # have access to $debuggeepid, so we have to read it from the file. 731 nlines=$2 732 allowExit="$3" 733 myCount=0 734 timeLimit=40 # wait a max of this many secs for a response from a jdb command 735 while [ 1 = 1 ] ; do 736 if [ -r $jdbOutFile ] ; then 737 # Something here causes jdb to complain about Unrecognized cmd on x86. 738 tail -$nlines $jdbOutFile | $grep -s "$1" > $devnull 2>&1 739 if [ $? = 0 ] ; then 740 # Found desired string 741 break 742 fi 743 fi 744 tail -2 $jdbOutFile | $grep -s "The application exited" > $devnull 2>&1 745 if [ $? = 0 ] ; then 746 # Found 'The application exited' 747 echo "--JDB finished: The application exited" >&2 748 if [ ! -z "$allowExit" ] ; then 749 # Exit is allowed 750 dofinish 751 fi 752 # Otherwise, it is an error if we don't find $1 753 if [ -r $jdbOutFile ] ; then 754 tail -$nlines $jdbOutFile | $grep -s "$1" > $devnull 2>&1 755 if [ $? = 0 ] ; then 756 break 757 fi 758 fi 759 dofail "JDB unexpectedly finished: Waited for jdb msg $1, but it never appeared" 760 fi 761 762 sleep ${sleep_seconds} 763 findPid $topPid 764 if [ $? != 0 ] ; then 765 echo "--Top process ($topPid) is dead. We better die too" >&2 766 dojstack 767 exit 1 768 fi 769 770 myCount=`expr $myCount + ${sleep_seconds}` 771 if [ $myCount -gt $timeLimit ] ; then 772 echo "--Fail: waitForJdbMsg timed out after $timeLimit seconds, looking for /$1/, in $nlines lines; exitting" >> $failFile 773 echo "vv jdbOutFile vvvvvvvvvvvvvvvvvvvvvvvvvvvv" >& 2 774 cat $jdbOutFile >& 2 775 echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" >& 2 776 dojstack 777 exit 1 778 fi 779 done 780 781} 782 783# Finishes JDB execution 784# Specify command to finish if it's needed 785dofinish() 786{ 787 if [ ! -z "$*" ] ; then 788 echo "--Finish execution with sending \"$*\" command to JDB" >&2 789 cmd "exitJdb" "$*" 790 else 791 echo "--Finish without sending \"quit\" command to JDB" >&2 792 fi 793 exit 0 794} 795 796# $1 is the string to print. If $2 exists, 797# it is the name of a file to print, ie, the name 798# of the file that contains the $1 string. 799dofail() 800{ 801 if [ ! -z "$jdbpid" ] ; then 802 # we are in the main process instead of the jdb process 803 echo " " >> $failFile 804 echo "--Fail: main: $*" >> $failFile 805 else 806 # Kill the debuggee ; it could be hung so 807 # we want to get rid of it as soon as possible. 808 killOrphans "killing debuggee" $debuggeeKeyword 809 # Kill debugger, it could be hung 810 killOrphans "killing debugger" $jdbKeyword 811 812 echo " " >>$failFile 813 echo "--Fail: $*" >> $failFile 814 fi 815 if [ ! -z "$2" ] ; then 816 echo "---- contents of $2 follows -------" >> $failFile 817 cat "$2" >> $failFile 818 echo "---------------" >>$failFile 819 fi 820 exit 1 821} 822 823 824redefineClass() 825{ 826 if [ -z "$1" ] ; then 827 vers=2 828 else 829 vers=`echo $1 | sed -e 's/@//'` 830 vers=`expr $vers + 1` 831 fi 832 833 cmd "redefine $pkgDot$classname $tmpFileDir/vers$vers/$classname.class" 834 835 cp $tmpFileDir/$classname.java.$vers \ 836 $tmpFileDir/$classname.java 837} 838 839mydojdbCmds() 840{ 841 # Wait for jdb to start before we start sending cmds 842 waitForJdbMsg ']' 1 843 # Send commands from the test 844 dojdbCmds 845 # Finish jdb with quit command 846 dofinish "quit" 847} 848 849startJdb() 850{ 851 if [ ! -r "$jdb" -a ! -r "$jdb.exe" ] ; then 852 dofail "$jdb does not exist" 853 fi 854 echo 855 echo "--Starting jdb, address=$address" 856 if [ -z "$address" ] ; then 857 # Let jdb choose the port and write it to stdout 858 mydojdbCmds | $jdb $jdbOptions -listenany | tee $jdbOutFile & 859 860 while [ 1 ] ; do 861 lastLine=`$grep 'Listening at address' $jdbOutFile` 862 if [ ! -z "$lastLine" ] ; then 863 break 864 fi 865 sleep 1 866 done 867 # jjh: we got the address ok, and seemed to start the debuggee 868 address=`echo $lastLine | sed -e 's@.*: *@@'` 869 else 870 mydojdbCmds | $jdb $jdbOptions -listen $address | tee $jdbOutFile & 871 fi 872 #echo address = $address 873 874 875 # this gets the pid of tee, at least it does on solaris 876 jdbpid=$! 877 878 # This fails on linux because there is an entry for each thread in jdb 879 # so we get a list of numbers in jdbpid 880 # jdbpid=`$psCmd | $grep -v grep | $grep ${orphanKeyword}_JDB | awk '{print $1}' | tr '\n\r' ' '` 881} 882 883startDebuggee() 884{ 885 args="$TESTVMOPTS $TESTJAVAOPTS" 886 887 if [ ! -z "$args" ] ; then 888 echo "--Starting debuggee with args from TESTVMOPTS and/or TESTJAVAOPTS: $args" 889 else 890 echo "--Starting debuggee" 891 fi 892 893 debuggeepid= 894 waitForJdbMsg Listening 4 895 896 beOption="-agentlib:jdwp=transport=$transport,address=$address,server=n,suspend=y" 897# beOption="-Xdebug -Xrunjdwp:transport=$transport,address=$address,server=n,suspend=y" 898 899 thecmd="$jdk/bin/$java $mode -classpath $tmpFileDir $baseArgs $args \ 900 -Djtreg.classDir=$TESTCLASSES \ 901 -showversion \ 902 $beOption \ 903 $pkgDot$classname" 904 echo "Cmd: $thecmd" 905 906 sh -c "$thecmd | tee $debuggeeOutFile" & 907 908 # Note that the java cmd and the tee cmd will be children of 909 # the sh process. We can use that to find them to kill them. 910 debuggeepid=$! 911 912 # Save this in a place where the jdb process can find it. 913 # Note that it is possible for the java cmd to abort during startup 914 # due to a bad classpath or whatever. 915 echo $debuggeepid > $debuggeepidFile 916} 917 918dojstack() 919{ 920 if [ -r "$jdk/bin/$jstack" ] ; then 921 # If jstack exists, so will jps 922 # Show stack traces of jdb and debuggee as a possible debugging aid. 923 jdbCmd=`$jdk/bin/jps -v | $grep $jdbKeyword` 924 realJdbPid=`echo "$jdbCmd" | sed -e 's@ TTY.*@@'` 925 if [ ! -z "$realJdbPid" ] ; then 926 echo "-- jdb process info ----------------------" >&2 927 echo " $jdbCmd" >&2 928 echo "-- jdb threads: jstack $realJdbPid" >&2 929 $jdk/bin/$jstack $realJdbPid >&2 930 echo "------------------------------------------" >&2 931 echo >&2 932 fi 933 debuggeeCmd=`$jdk/bin/jps -v | $grep $debuggeeKeyword` 934 realDebuggeePid=`echo "$debuggeeCmd" | sed -e 's@ .*@@'` 935 if [ ! -z "$realDebuggeePid" ] ; then 936 echo "-- debuggee process info ----------------------" >&2 937 echo " $debuggeeCmd" >&2 938 echo "-- debuggee threads: jstack $moption $realDebuggeePid" >&2 939 $jdk/bin/$jstack $realDebuggeePid >&2 940 echo "=============================================" >&2 941 echo >&2 942 fi 943 fi 944} 945 946waitForFinish() 947{ 948 # This is the main process 949 # Wait for the jdb process to finish, or some error to occur 950 951 while [ 1 = 1 ] ; do 952 findPid $jdbpid 953 if [ $? != 0 ] ; then 954 break 955 fi 956 957 # (Don't use jdbFailIfPresent here since it is not safe 958 # to call from different processes) 959 $grep -s 'Input stream closed' $jdbOutFile > $devnull 2>&1 960 if [ $? = 0 ] ; then 961 dofail "jdb input stream closed prematurely" 962 fi 963 964 # If a failure has occured, quit 965 if [ -r "$failFile" ] ; then 966 break 967 fi 968 969 sleep ${sleep_seconds} 970 done 971 972 # jdb exited because its input stream closed prematurely 973 # (Don't use jdbFailIfPresent here since it is not safe 974 # to call from different processes) 975 $grep -s 'Input stream closed' $jdbOutFile > $devnull 2>&1 976 if [ $? = 0 ] ; then 977 dofail "jdb input stream closed prematurely" 978 fi 979 980 # It is necessary here to avoid the situation when JDB exited but 981 # mydojdbCmds() didn't finish because it waits for JDB message 982 # in waitForJdbMsg(), at the same time main process will finish 983 # the execution with no errors. 984 # To avoid that, wait for spawned processes to finish 985 case "$osname" in 986 SunOS) 987 # `wait` function doesn't work in Solaris shell as in bash, 988 # so create replacement that finds mydojdbCmds() shell process 989 # and waits for its finish 990 cmdsPid= 991 # get list of processes except main process with $topPid 992 processes=`$psCmd | $grep -v "$grep" | $grep -v $topPid | awk '{print $1}'` 993 for pid in $processes; do 994 # for each process grep its full args string for test name $0 995 # $0 contains full test name with path 996 pargs -l $pid 2>$devnull | $grep "$0" >$devnull 2>&1 997 if [ $? = 0 ] ; then 998 cmdsPid=$pid 999 break 1000 fi 1001 done 1002 echo "--waitForFinish: Waiting for mydojdbCmds() to finish" >&2 1003 while [ 1 = 1 ] ; do 1004 findPid $cmdsPid 1005 if [ $? != 0 ] ; then 1006 break 1007 fi 1008 sleep ${sleep_seconds} 1009 done 1010 ;; 1011 *) 1012 echo "--waitForFinish: Waiting for all processes to finish" >&2 1013 wait 1014 ;; 1015 esac 1016 1017 if [ -r "$failFile" ] ; then 1018 ls -l "$failFile" >&2 1019 echo "<waitForFinish:_begin_failFile_contents>" >&2 1020 cat "$failFile" >&2 1021 echo "<waitForFinish:_end_failFile_contents>" >&2 1022 exit 1 1023 fi 1024} 1025 1026# $1 is the filename, $2 is the string to look for, 1027# $3 is the number of lines to search (from the end) 1028grepForString() 1029{ 1030 if [ -z "$3" ] ; then 1031 theCmd=cat 1032 else 1033 theCmd="tail -$3" 1034 fi 1035 1036 case "$2" in 1037 *\>*) 1038 # Target string contains a '>' so we better not ignore it 1039 $theCmd $1 | $grep -s "$2" > $devnull 2>&1 1040 stat="$?" 1041 ;; 1042 *) 1043 # Target string does not contain a '>'. 1044 # NOTE: if $1 does not end with a new line, piping it to sed 1045 # doesn't include the chars on the last line. Detect this 1046 # case, and add a new line. 1047 theFile="$1" 1048 if [ `tail -1 "$theFile" | wc -l | sed -e 's@ @@g'` = 0 ] ; then 1049 # The target file doesn't end with a new line so we have 1050 # add one to a copy of the target file so the sed command 1051 # below can filter that last line. 1052 cp "$theFile" "$theFile.tmp" 1053 theFile="$theFile.tmp" 1054 echo >> "$theFile" 1055 fi 1056 1057 # See bug 6220903. Sometimes the jdb prompt chars ('> ') can 1058 # get interleaved in the target file which can keep us from 1059 # matching the target string. 1060 $theCmd "$theFile" | sed -e 's@> @@g' -e 's@>@@g' \ 1061 | $grep -s "$2" > $devnull 2>&1 1062 stat=$? 1063 if [ "$theFile" != "$1" ]; then 1064 # remove the copy of the target file 1065 rm -f "$theFile" 1066 fi 1067 unset theFile 1068 esac 1069 1070 return $stat 1071} 1072 1073# $1 is the filename, $2 is the regexp to match and return, 1074# $3 is the number of lines to search (from the end) 1075matchRegexp() 1076{ 1077 if [ -z "$3" ] ; then 1078 theCmd=cat 1079 else 1080 theCmd="tail -$3" 1081 fi 1082 1083 case "$2" in 1084 *\>*) 1085 # Target string contains a '>' so we better not ignore it 1086 res=`$theCmd $1 | sed -e "$2"` 1087 ;; 1088 *) 1089 # Target string does not contain a '>'. 1090 # NOTE: if $1 does not end with a new line, piping it to sed 1091 # doesn't include the chars on the last line. Detect this 1092 # case, and add a new line. 1093 theFile="$1" 1094 if [ `tail -1 "$theFile" | wc -l | sed -e 's@ @@g'` = 0 ] ; then 1095 # The target file doesn't end with a new line so we have 1096 # add one to a copy of the target file so the sed command 1097 # below can filter that last line. 1098 cp "$theFile" "$theFile.tmp" 1099 theFile="$theFile.tmp" 1100 echo >> "$theFile" 1101 fi 1102 1103 # See bug 6220903. Sometimes the jdb prompt chars ('> ') can 1104 # get interleaved in the target file which can keep us from 1105 # matching the target string. 1106 res=`$theCmd "$theFile" | sed -e 's@> @@g' -e 's@>@@g' \ 1107 | sed -e "$2"` 1108 if [ "$theFile" != "$1" ]; then 1109 # remove the copy of the target file 1110 rm -f "$theFile" 1111 fi 1112 unset theFile 1113 esac 1114 return $res 1115} 1116 1117# $1 is the filename, $2 is the string to look for, 1118# $3 is the number of lines to search (from the end) 1119failIfPresent() 1120{ 1121 if [ -r "$1" ] ; then 1122 grepForString "$1" "$2" "$3" 1123 if [ $? = 0 ] ; then 1124 dofail "Error output found: \"$2\" in $1" $1 1125 fi 1126 fi 1127} 1128 1129# $1 is the filename, $2 is the string to look for 1130# $3 is the number of lines to search (from the end) 1131failIfNotPresent() 1132{ 1133 if [ ! -r "$1" ] ; then 1134 dofail "Required output \"$2\" not found in $1" 1135 fi 1136 grepForString "$1" "$2" "$3" 1137 if [ $? != 0 ] ; then 1138 dofail "Required output \"$2\" not found in $1" $1 1139 fi 1140 1141} 1142 1143# fail if $1 is not in the jdb output 1144# $2 is the number of lines to search (from the end) 1145jdbFailIfNotPresent() 1146{ 1147 failIfNotPresent $jdbOutFile "$1" $2 1148} 1149 1150# fail if $1 is not in the debuggee output 1151# $2 is the number of lines to search (from the end) 1152debuggeeFailIfNotPresent() 1153{ 1154 failIfNotPresent $debuggeeOutFile "$1" $2 1155} 1156 1157# fail if $1 is in the jdb output 1158# $2 is the number of lines to search (from the end) 1159jdbFailIfPresent() 1160{ 1161 failIfPresent $jdbOutFile "$1" $2 1162} 1163 1164# fail if $1 is in the debuggee output 1165# $2 is the number of lines to search (from the end) 1166debuggeeFailIfPresent() 1167{ 1168 failIfPresent $debuggeeOutFile "$1" $2 1169} 1170 1171# match and return the output from the regexp $1 in the debuggee output 1172# $2 is the number of lines to search (from the end) 1173debuggeeMatchRegexp() 1174{ 1175 matchRegexp $debuggeeOutFile "$1" $2 1176} 1177 1178 1179# This should really be named 'done' instead of pass. 1180pass() 1181{ 1182 if [ ! -r "$failFile" ] ; then 1183 echo 1184 echo "--Done: test passed" 1185 exit 0 1186 else 1187 ls -l "$failFile" >&2 1188 echo "<pass:_begin_failFile_contents>" >&2 1189 cat "$failFile" >&2 1190 echo "<pass:_end_failFile_contents>" >&2 1191 fi 1192} 1193 1194runit() 1195{ 1196 setup 1197 docompile 1198 startJdb 1199 startDebuggee 1200 waitForFinish 1201 1202 # in hs_err file from 1.3.1 1203 debuggeeFailIfPresent "Virtual Machine Error" 1204 1205 # in hs_err file from 1.4.2, 1.5: An unexpected error 1206 debuggeeFailIfPresent "An unexpected error" 1207 1208 # in hs_err file from 1.4.2, 1.5: Internal error 1209 debuggeeFailIfPresent "Internal error" 1210 1211 1212 # Don't know how this arises 1213 debuggeeFailIfPresent "An unexpected exception" 1214 1215 # Don't know how this arises 1216 debuggeeFailIfPresent "Internal exception" 1217} 1218