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