# HG changeset patch # User vkempik # Date 1495109673 14400 # Node ID 8ead62daaa47aec3d52f62de3ae55f721b485074 # Parent c872a196b75f64ce24de3fb0ef72c3804c651ab8 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 diff -r c872a196b75f -r 8ead62daaa47 hotspot/src/os/windows/vm/os_windows.cpp --- 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) { diff -r c872a196b75f -r 8ead62daaa47 hotspot/src/share/vm/utilities/vmError.cpp --- 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); diff -r c872a196b75f -r 8ead62daaa47 hotspot/test/runtime/ErrorHandling/TestOnOutOfMemoryError.java --- 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= + * @summary Test using single and multiple -XX:OnOutOfMemoryError= * @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"); } }