diff --git a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/test/SubprocessUtil.java b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/test/SubprocessUtil.java index a4f40b2b43e6..3d6d6d122c60 100644 --- a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/test/SubprocessUtil.java +++ b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/test/SubprocessUtil.java @@ -335,41 +335,53 @@ public String toString() { /** * Returns the process execution as a string with a header line followed by one or more body * lines followed by a trailer with a new line. - * - * The header is {@code "----------subprocess[]:(/)----------"} where + *

+ * The header is + * {@code "----------subprocess[pid=]:(lines=, chars=)----------"} where * {@code pid} is the id of the process and {@code chars} and {@code lines} provide the * dimensions of the body. - * + *

* The sections in the body are the environment variables (key: "env"), the command line * (key: "cmd"), the lines of output produced (key: "output") and the exit code (key: * "exitCode"). - * - * The trailer is {@code "==========subprocess[]=========="} + *

+ * The trailer is {@code "==========subprocess[pid=]=========="} * * @param sections selects which sections are in the body. If null, all sections are * included. */ public String asString(Map sections) { + String subSectionSeparator = "--------------"; Formatter msg = new Formatter(); if (include(sections, "env")) { if (env != null && !env.isEmpty()) { - msg.format("env"); + Formatter envBuf = new Formatter(); + envBuf.format("env"); for (Map.Entry e : env.entrySet()) { - msg.format(" %s=%s", e.getKey(), quoteShellArg(e.getValue())); + envBuf.format(" %s=%s", e.getKey(), quoteShellArg(e.getValue())); } - msg.format("\\%n"); + String envSection = envBuf.toString(); + msg.format("%sEnvironment[length=%d]%s%n", subSectionSeparator, envSection.length(), subSectionSeparator); + msg.format("%s%n", envSection); } } if (include(sections, "cmd")) { - msg.format("%s%n", CollectionsUtil.mapAndJoin(command, e -> quoteShellArg(String.valueOf(e)), " ")); + String cmdSection = CollectionsUtil.mapAndJoin(command, e -> quoteShellArg(String.valueOf(e)), " "); + msg.format("%sCommand[length=%d]%s%n", subSectionSeparator, cmdSection.length(), subSectionSeparator); + msg.format("%s%n", cmdSection); } if (include(sections, "output")) { + Formatter outputBuf = new Formatter(); for (String line : output) { - msg.format("%s%n", line); + outputBuf.format("%s%n", line); } + String outputSection = outputBuf.toString(); + msg.format("%sOutput[length=%d]%s%n", subSectionSeparator, outputSection.length(), subSectionSeparator); + msg.format("%s", outputSection); } if (include(sections, "exitCode")) { - msg.format("exit code: %s%n", exitCode); + msg.format("%sExit code%s%n", subSectionSeparator, subSectionSeparator); + msg.format("%d%n", exitCode); } String body = msg.toString(); if (!body.endsWith(System.lineSeparator())) { @@ -377,8 +389,8 @@ public String asString(Map sections) { } long lines = body.chars().filter(ch -> ch == '\n').count(); int chars = body.length(); - String head = String.format("----------subprocess[%d]:(%d/%d)----------", pid, lines, chars); - String tail = String.format("==========subprocess[%d]==========", pid); + String head = String.format("----------Subprocess[pid=%d]:(lines=%d, chars=%d)----------", pid, lines, chars); + String tail = String.format("==========Subprocess[pid=%d]==========", pid); return String.format("%s%n%s%s%n", head, body, tail); } diff --git a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/truffle/test/TruffleHostInliningTest.java b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/truffle/test/TruffleHostInliningTest.java index 452853936abb..7f7f2cb7e649 100644 --- a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/truffle/test/TruffleHostInliningTest.java +++ b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/truffle/test/TruffleHostInliningTest.java @@ -27,6 +27,7 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.time.Duration; import java.util.function.Consumer; import org.junit.Assert; @@ -75,7 +76,8 @@ private void runHostCompilationTest(Runnable inProcess, Consumer log) th inProcess.run(); } else { File logFile = File.createTempFile(getClass().getSimpleName(), "test"); - SubprocessTestUtils.newBuilder(getClass(), inProcess).failOnNonZeroExit(true).// + SubprocessTestUtils.newBuilder(getClass(), inProcess).// + failOnNonZeroExit(true).// prefixVmOption("-Djdk.graal.Log=HostInliningPhase,~CanonicalizerPhase,~InlineGraph", "-Djdk.graal.MethodFilter=" + TruffleHostInliningTest.class.getSimpleName() + ".*", "-Djdk.graal.CompilationFailureAction=Print", @@ -83,6 +85,8 @@ private void runHostCompilationTest(Runnable inProcess, Consumer log) th String.format("-XX:CompileCommand=compileonly,%s::*", TruffleHostInliningTest.class.getName()), "-Xbatch").// force synchronous compilation postfixVmOption("-XX:+UseJVMCICompiler").// force Graal host compilation + // The default 2 minutes timeout is not enough on linux-aarch gates + timeout(Duration.ofMinutes(5)).// onExit((_) -> { try { log.accept((Files.readString(logFile.toPath()))); @@ -90,7 +94,8 @@ private void runHostCompilationTest(Runnable inProcess, Consumer log) th throw new AssertionError(e); } logFile.delete(); - }).run(); + }).// + run(); } } diff --git a/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/SubprocessTestUtils.java b/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/SubprocessTestUtils.java index 201328dcd8d0..ace7fd9aedfb 100644 --- a/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/SubprocessTestUtils.java +++ b/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/SubprocessTestUtils.java @@ -409,40 +409,52 @@ private Subprocess(List command, Map env, long pid, int /** * Returns the process execution as a string with a header line followed by one or more body * lines followed by a trailer with a new line. - * - * The header is {@code "----------subprocess[]:(/)----------"} where + *

+ * The header is + * {@code "----------subprocess[pid=]:(lines=, chars=)----------"} where * {@code pid} is the id of the process and {@code chars} and {@code lines} provide the * dimensions of the body. - * - * The sections in the body are the environment variables {@link Section#ENVIRONMENT}, the - * command line {@link Section#COMMAND}, the lines of output produced {@link Section#OUTPUT} - * and the exit code {@link Section#EXIT_CODE}. - * - * The trailer is {@code "==========subprocess[]=========="} + *

+ * The sections in the body are the environment variables (key: "env"), the command line + * (key: "cmd"), the lines of output produced (key: "output") and the exit code (key: + * "exitCode"). + *

+ * The trailer is {@code "==========subprocess[pid=]=========="} * * @param sections selects which sections are in the body. */ private String asString(Set

sections) { + String subSectionSeparator = "--------------"; Formatter msg = new Formatter(); if (sections.contains(Section.ENVIRONMENT)) { if (env != null && !env.isEmpty()) { - msg.format("env"); + Formatter envBuf = new Formatter(); + envBuf.format("env"); for (Map.Entry e : env.entrySet()) { - msg.format(" %s=%s", e.getKey(), quoteShellArg(e.getValue())); + envBuf.format(" %s=%s", e.getKey(), quoteShellArg(e.getValue())); } - msg.format("\\%n"); + String envSection = envBuf.toString(); + msg.format("%sEnvironment[length=%d]%s%n", subSectionSeparator, envSection.length(), subSectionSeparator); + msg.format("%s%n", envSection); } } if (sections.contains(Section.COMMAND)) { - msg.format("%s%n", command.stream().map((e) -> quoteShellArg(String.valueOf(e))).collect(Collectors.joining(" "))); + String cmdSection = command.stream().map((e) -> quoteShellArg(String.valueOf(e))).collect(Collectors.joining(" ")); + msg.format("%sCommand[length=%d]%s%n", subSectionSeparator, cmdSection.length(), subSectionSeparator); + msg.format("%s%n", cmdSection); } if (sections.contains(Section.OUTPUT)) { + Formatter outputBuf = new Formatter(); for (String line : output) { - msg.format("%s%n", line); + outputBuf.format("%s%n", line); } + String outputSection = outputBuf.toString(); + msg.format("%sOutput[length=%d]%s%n", subSectionSeparator, outputSection.length(), subSectionSeparator); + msg.format("%s", outputSection); } if (sections.contains(Section.EXIT_CODE)) { - msg.format("exit code: %s%n", exitCode); + msg.format("%sExit code%s%n", subSectionSeparator, subSectionSeparator); + msg.format("%d%n", exitCode); } String body = msg.toString(); if (!body.endsWith(System.lineSeparator())) { @@ -450,8 +462,8 @@ private String asString(Set
sections) { } long lines = body.chars().filter(ch -> ch == '\n').count(); int chars = body.length(); - String head = String.format("----------subprocess[%d]:(%d/%d)----------", pid, lines, chars); - String tail = String.format("==========subprocess[%d]==========", pid); + String head = String.format("----------Subprocess[pid=%d]:(lines=%d, chars=%d)----------", pid, lines, chars); + String tail = String.format("==========Subprocess[pid=%d]==========", pid); return String.format("%s%n%s%s%n", head, body, tail); } @@ -857,6 +869,7 @@ private static Subprocess process(List command, Map env, outputReader.start(); boolean finishedOnTime = process.waitFor(timeout.getSeconds(), TimeUnit.SECONDS); if (!finishedOnTime) { + printError("Subprocess %d did not finish within the specified timeout: %s.", process.pid(), timeout); dumpThreads(process.toHandle()); process.destroyForcibly().waitFor(); } @@ -999,11 +1012,12 @@ private static void dumpThreads(ProcessHandle process) { CompositeData[] result = (CompositeData[]) mbeanConnection.invoke(new ObjectName("java.lang:type=Threading"), "dumpAllThreads", new Object[]{true, true}, new String[]{boolean.class.getName(), boolean.class.getName()}); StringWriter messageBuilder = new StringWriter(); - PrintWriter out = new PrintWriter(new StringWriter()); - out.printf("%nDumping subprocess threads on timeout%n"); + PrintWriter out = new PrintWriter(messageBuilder); + out.printf("Dumping subprocess threads on timeout%n"); for (CompositeData element : result) { dumpThread(ThreadInfo.from(element), out); } + out.flush(); printError(messageBuilder.toString()); } } finally {