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