8177522: -XX:OnOutOfMemoryError does not work if supplied twice on windows
Summary: use cmd /c on windows to execute onError commands
Reviewed-by: dholmes, hseigel
--- a/hotspot/src/os/windows/vm/os_windows.cpp Wed May 17 23:36:19 2017 +0200
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Thu May 18 08:14:33 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -5250,12 +5250,30 @@
int os::fork_and_exec(char* cmd) {
STARTUPINFO si;
PROCESS_INFORMATION pi;
-
+ DWORD exit_code;
+
+ char * cmd_string;
+ char * cmd_prefix = "cmd /C ";
+ size_t len = strlen(cmd) + strlen(cmd_prefix) + 1;
+ cmd_string = NEW_C_HEAP_ARRAY_RETURN_NULL(char, len, mtInternal);
+ if (cmd_string == NULL) {
+ return -1;
+ }
+ cmd_string[0] = '\0';
+ strcat(cmd_string, cmd_prefix);
+ strcat(cmd_string, cmd);
+
+ // now replace all '\n' with '&'
+ char * substring = cmd_string;
+ while ((substring = strchr(substring, '\n')) != NULL) {
+ substring[0] = '&';
+ substring++;
+ }
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
memset(&pi, 0, sizeof(pi));
BOOL rslt = CreateProcess(NULL, // executable name - use command line
- cmd, // command line
+ cmd_string, // command line
NULL, // process security attribute
NULL, // thread security attribute
TRUE, // inherits system handles
@@ -5269,17 +5287,17 @@
// Wait until child process exits.
WaitForSingleObject(pi.hProcess, INFINITE);
- DWORD exit_code;
GetExitCodeProcess(pi.hProcess, &exit_code);
// Close process and thread handles.
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
-
- return (int)exit_code;
} else {
- return -1;
- }
+ exit_code = -1;
+ }
+
+ FREE_C_HEAP_ARRAY(char, cmd_string);
+ return (int)exit_code;
}
bool os::find(address addr, outputStream* st) {
--- a/hotspot/src/share/vm/utilities/vmError.cpp Wed May 17 23:36:19 2017 +0200
+++ b/hotspot/src/share/vm/utilities/vmError.cpp Thu May 18 08:14:33 2017 -0400
@@ -1396,6 +1396,8 @@
out.print_raw ("/bin/sh -c ");
#elif defined(SOLARIS)
out.print_raw ("/usr/bin/sh -c ");
+#elif defined(WINDOWS)
+ out.print_raw ("cmd /C ");
#endif
out.print_raw ("\"");
out.print_raw (cmd);
--- a/hotspot/test/runtime/ErrorHandling/TestOnOutOfMemoryError.java Wed May 17 23:36:19 2017 +0200
+++ b/hotspot/test/runtime/ErrorHandling/TestOnOutOfMemoryError.java Thu May 18 08:14:33 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -23,11 +23,11 @@
/*
* @test TestOnOutOfMemoryError
- * @summary Test using -XX:OnOutOfMemoryError=<cmd>
+ * @summary Test using single and multiple -XX:OnOutOfMemoryError=<cmd>
* @modules java.base/jdk.internal.misc
* @library /test/lib
* @run main TestOnOutOfMemoryError
- * @bug 8078470
+ * @bug 8078470 8177522
*/
import jdk.test.lib.process.ProcessTools;
@@ -44,13 +44,22 @@
}
// else this is the main test
- String msg = "Test Succeeded";
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
- "-XX:OnOutOfMemoryError=echo " + msg,
+ String msg1 = "Test1 Succeeded";
+ String msg2 = "Test2 Succeeded";
+ ProcessBuilder pb_single = ProcessTools.createJavaProcessBuilder(
+ "-XX:OnOutOfMemoryError=echo " + msg1,
TestOnOutOfMemoryError.class.getName(),
"throwOOME");
- OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ ProcessBuilder pb_multiple = ProcessTools.createJavaProcessBuilder(
+ "-XX:OnOutOfMemoryError=echo " + msg1,
+ "-XX:OnOutOfMemoryError=echo " + msg2,
+ TestOnOutOfMemoryError.class.getName(),
+ "throwOOME");
+
+ OutputAnalyzer output_single = new OutputAnalyzer(pb_single.start());
+
+ OutputAnalyzer output_multiple = new OutputAnalyzer(pb_multiple.start());
/* Actual output should look like this:
#
@@ -64,8 +73,13 @@
So we don't want to match on the "# Executing ..." line, and they
both get written to stdout.
*/
- output.shouldContain("Requested array size exceeds VM limit");
- output.stdoutShouldMatch("^" + msg); // match start of line only
+ output_single.shouldContain("Requested array size exceeds VM limit");
+ output_single.stdoutShouldMatch("^" + msg1); // match start of line only
+
+ output_multiple.shouldContain("Requested array size exceeds VM limit");
+ output_multiple.stdoutShouldMatch("^" + msg1); // match start of line only
+ output_multiple.stdoutShouldMatch("^" + msg2); // match start of line only
+
System.out.println("PASSED");
}
}