--- old/test/jdk/com/sun/jdi/DeferredStepTest.sh 2018-10-04 15:56:45.748225700 -0700 +++ /dev/null 2018-10-04 15:56:46.000000000 -0700 @@ -1,183 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# @ test -# This is a manual test. The script isn't smart enough -# to detect the correct ordering of the output since it -# is produced by multiple threads and can be interleaved -# in many different ways. -# -# @bug 4629548 -# @summary Deferred StepRequests are lost in multithreaded debuggee -# @author Jim Holmlund -# -# @run shell/manual DeferredStepTest.sh - -# Run this script to see the bug. See comments at the end -# of the .java file for info on what the bug looks like. - -# These are variables that can be set to control execution - -#pkg=untitled7 -classname=DeferredStepTest -#compileOptions=-g -#java=java_g -#mode=-Xcomp - -createJavaFile() -{ - cat < $classname.java.1 -public class $classname { - static class jj1 implements Runnable { - public void run() { - int count = 0; - - for ( int ii = 0; ii < 10; ii++) { // line 6 - int intInPotato04 = 666; // line 7 - ++count; // line 8; @1 breakpoint - System.out.println("Thread: " + Thread.currentThread().getName()); // line 9 - } - } - } - - static class jj2 implements Runnable { - public void run() { - int count2 = 0; - - for (int ii = 0; ii < 10; ii++) { // line 18 - String StringInPotato05 = "I am"; // line 19 - ++count2; // line 20; @1 breakpoint - System.out.println("Thread: " + Thread.currentThread().getName()); // line 21 - } - } - } - - public static void main(String argv[]) { - System.out.println("Version = " + System.getProperty("java.version")); - - jj1 aRP = new jj1(); - jj2 asRP = new jj2(); - new Thread(aRP, "jj1 *").start(); - new Thread(asRP, "jj2 **").start(); -// new Thread(aRP, "jj3 ***").start(); -// new Thread(asRP, "jj4 ****").start(); - } -} - -/**************************** -To see this bug, do this - - jdb DeferredStep - stop at DeferredStepTest$jj1:8 - stop at DeferredStepTest$jj2:20 - run - next - next - : - -********/ - -EOF -} - -#sleepcmd="sleep 2" - -# This is called to feed cmds to jdb. -dojdbCmds() -{ - #set -x - # We can't use setBkpts because it can only set bkpts in one class :-( - #setBkpts @1 - cmd stop at $classname'$jj1:8' - cmd stop at $classname'$jj2:20' - #cmd run; $sleepcmd - runToBkpt @1 - cmd next; $sleepcmd - cmd next; $sleepcmd - cmd next; $sleepcmd - cmd next; $sleepcmd - cmd next; $sleepcmd - cmd next; $sleepcmd - cmd next; $sleepcmd - cmd next; $sleepcmd - cmd next; $sleepcmd - cmd next; $sleepcmd - cmd next; $sleepcmd - cmd next; $sleepcmd - cmd next; $sleepcmd - cmd next; $sleepcmd - cmd next; $sleepcmd -} - -mysetup() -{ - if [ -z "$TESTSRC" ] ; then - TESTSRC=. - fi - - for ii in . $TESTSRC $TESTSRC/.. ; do - if [ -r "$ii/ShellScaffold.sh" ] ; then - . $ii/ShellScaffold.sh - break - fi - done -} - - -# You could replace this next line with the contents -# of ShellScaffold.sh and this script will run just the same. -mysetup - -cat < threadData = new HashMap<>(); + + private Pattern threadRegexp = Pattern.compile("^(.+)\\[\\d+\\].*"); + private Pattern lineRegexp = Pattern.compile("^(\\d+)\\b.*", Pattern.MULTILINE); + + // returns the 1st group of the pattern. + private String parse(Pattern p, String input) { + Matcher m = p.matcher(input); + if (!m.find()) { + throw new RuntimeException("Input '" + input + "' does not matches '" + p.pattern() + "'"); + } + return m.group(1); + } + + private void next() { + List reply = jdb.command(JdbCommand.next()); + /* + * Each "next" produces something like ("Breakpoint hit" line only if the line has BP) + * Step completed: + * Breakpoint hit: "thread=jj2", DeferredStepTestTarg$jj2.run(), line=74 bci=12 + * 74 ++count2; // @2 breakpoint + * + * jj2[1] + */ + // detect thread from the last line + String lastLine = reply.get(reply.size() - 1); + String threadName = parse(threadRegexp, lastLine); + String wholeReply = reply.stream().collect(Collectors.joining(Utils.NEW_LINE)); + int lineNum = Integer.parseInt(parse(lineRegexp, wholeReply)); + + System.out.println("got: thread=" + threadName + ", line=" + lineNum); + + ThreadData data = threadData.get(threadName); + if (data == null) { + data = new ThreadData(); + threadData.put(threadName, data); + } + do { + if (data.lastLine < 0) { + // the 1st stop in the thread + break; + } + if (lineNum == data.lastLine + 1) { + // expected. + break; + } + if (lineNum < data.lastLine) { + // looks like step to the beginning of the cycle + if (data.minLine > 0) { + // minLine and maxLine are not set - verify + Asserts.assertEquals(lineNum, data.minLine, threadName + " - minLine"); + Asserts.assertEquals(data.lastLine, data.maxLine, threadName + " - maxLine"); + } else { + // set minLine/maxLine + data.minLine = lineNum; + data.maxLine = data.lastLine; + } + break; + } + // + throw new RuntimeException(threadName + " (line " + lineNum + ") - unexpected." + + " lastLine=" + data.lastLine + ", minLine=" + data.minLine + ", maxLine=" + data.maxLine); + } while (false); + data.lastLine = lineNum; + } + + @Override + protected void runCases() { + setBreakpoints(jdb, DeferredStepTestTarg.jj1.class.getName(), + getTestSourcePath("DeferredStepTest.java"), 1); + setBreakpoints(jdb, DeferredStepTestTarg.jj2.class.getName(), + getTestSourcePath("DeferredStepTest.java"), 2); + + // Run to breakpoint #1 + jdb.command(JdbCommand.run()); + + // 2 cycles with 4 lines each - maximum 80 stops + for (int i=0; i<50; i++) { + next(); + } + } +}