diff --git a/debugtools/DDR_VM/src/com/ibm/j9ddr/corereaders/minidump/WindowsProcessAddressSpace.java b/debugtools/DDR_VM/src/com/ibm/j9ddr/corereaders/minidump/WindowsProcessAddressSpace.java index 78735428b67..b3c78aa9fa2 100644 --- a/debugtools/DDR_VM/src/com/ibm/j9ddr/corereaders/minidump/WindowsProcessAddressSpace.java +++ b/debugtools/DDR_VM/src/com/ibm/j9ddr/corereaders/minidump/WindowsProcessAddressSpace.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. and others + * Copyright (c) 2009, 2022 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -80,39 +80,41 @@ public int hashCode() { } /** - * This method tries to get environment variables by iterating through modules. - * It returns the one with environment var "IBM_JAVA_COMMAND_LINE" - * If there is no module with IBM_JAVA_COMMAND_LINE, then it returns the last one. - * - * @return Properties instance of environment variables. + * This method tries to get environment variables by iterating through modules. + * It returns the one with environment variable "OPENJ9_JAVA_COMMAND_LINE" or + * "IBM_JAVA_COMMAND_LINE". If no module has either, then it returns the last one. + * + * @return Properties instance of environment variables * @throws DataUnavailableException * @throws CorruptDataException */ public Properties getEnvironmentVariables() throws DataUnavailableException, CorruptDataException { if (null == environment) { - LinkedList environSymbols = getEnvironmentSymbols(); - ISymbol environ = null; - - if (0 == environSymbols.size()) { + List environSymbols = getEnvironmentSymbols(); + + if (environSymbols.isEmpty()) { throw new DataUnavailableException("Couldn't find environment symbol"); } - - /* There might be more than one module with environment variables. Use the one that has IBM_JAVA_COMMAND_LINE */ - for (int i = 0; i < environSymbols.size(); i++ ) { - environ = environSymbols.get(i); + + /* + * There might be more than one module with environment variables. + * Use the one that has OPENJ9_JAVA_COMMAND_LINE or IBM_JAVA_COMMAND_LINE. + */ + for (ISymbol environ : environSymbols) { long environPointer = getPointerAt(environ.getAddress()); - environment = EnvironmentUtils.readEnvironment(this,environPointer); - if (environment.containsKey("IBM_JAVA_COMMAND_LINE")) { + environment = EnvironmentUtils.readEnvironment(this, environPointer); + if (environment.containsKey("OPENJ9_JAVA_COMMAND_LINE") + || environment.containsKey("IBM_JAVA_COMMAND_LINE") + ) { break; } } } - + return environment; } - /** * This method returns a list of symbols with the name "_environ" * diff --git a/debugtools/DDR_VM/src/com/ibm/j9ddr/view/dtfj/image/J9DDRImageProcess.java b/debugtools/DDR_VM/src/com/ibm/j9ddr/view/dtfj/image/J9DDRImageProcess.java index e994e80ad43..217a47ad7ab 100644 --- a/debugtools/DDR_VM/src/com/ibm/j9ddr/view/dtfj/image/J9DDRImageProcess.java +++ b/debugtools/DDR_VM/src/com/ibm/j9ddr/view/dtfj/image/J9DDRImageProcess.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 1991, 2019 IBM Corp. and others + * Copyright (c) 1991, 2022 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -63,7 +63,8 @@ */ public class J9DDRImageProcess implements ImageProcess { - private static final String JAVA_COMMAND_LINE_ENVIRONMENT_VARIABLE = "IBM_JAVA_COMMAND_LINE"; + private static final String JAVA_COMMAND_LINE_ENVIRONMENT_VARIABLE = "OPENJ9_JAVA_COMMAND_LINE"; + private static final String LEGACY_JAVA_COMMAND_LINE_ENVIRONMENT_VARIABLE = "IBM_JAVA_COMMAND_LINE"; private final IProcess process; private boolean processDataSet = false; private ProcessData j9rasProcessData; @@ -149,10 +150,17 @@ public String getCommandLine() throws DataUnavailable, CorruptDataException { try { Properties environment = getEnvironment(); String javaCommandLine = environment.getProperty(JAVA_COMMAND_LINE_ENVIRONMENT_VARIABLE); - + + if (javaCommandLine != null) { + return javaCommandLine; + } + + javaCommandLine = environment.getProperty(LEGACY_JAVA_COMMAND_LINE_ENVIRONMENT_VARIABLE); + if (javaCommandLine != null) { return javaCommandLine; } + return process.getCommandLine(); } catch (com.ibm.j9ddr.CorruptDataException e) { throw new DTFJCorruptDataException(process,e); diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewElfDump.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewElfDump.java index 200a1c7ab65..bdb893bfd2f 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewElfDump.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewElfDump.java @@ -1,6 +1,6 @@ /*[INCLUDE-IF Sidecar18-SE]*/ /******************************************************************************* - * Copyright (c) 2004, 2020 IBM Corp. and others + * Copyright (c) 2004, 2022 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -1493,7 +1493,10 @@ private Object readProcess(DataEntry entry, Builder builder, Object addressSpace Properties environment = getEnvironmentVariables(builder); String alternateCommandLine = ""; //$NON-NLS-1$ if (null != environment) { - alternateCommandLine = environment.getProperty("IBM_JAVA_COMMAND_LINE", ""); //$NON-NLS-1$ //$NON-NLS-2$ + alternateCommandLine = environment.getProperty("OPENJ9_JAVA_COMMAND_LINE", null); //$NON-NLS-1$ + if (null == alternateCommandLine) { + alternateCommandLine = environment.getProperty("IBM_JAVA_COMMAND_LINE", ""); //$NON-NLS-1$ //$NON-NLS-2$ + } } String commandLine = dumpCommandLine.length() >= alternateCommandLine.length() ? dumpCommandLine : alternateCommandLine; @@ -1583,7 +1586,8 @@ private List readModules(Builder builder, Object addressSpace, String executa } else { // Use override for the executable name. This supports the jextract -f option, for // cases where the launcher path+name is truncated by the 80 character OS limit, AND it was a - // custom launcher, so the alternative IBM_JAVA_COMMAND_LINE property was not set. + // custom launcher, so the alternative property OPENJ9_JAVA_COMMAND_LINE (or IBM_JAVA_COMMAND_LINE) + // was not set. file = _findFileInPath(builder, overrideExecutableName, classPath); } diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewZosDump.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewZosDump.java index 4ae363853ca..ff3b60ba4d3 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewZosDump.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/corereaders/NewZosDump.java @@ -1,6 +1,6 @@ /*[INCLUDE-IF Sidecar18-SE]*/ /******************************************************************************* - * Copyright (c) 2004, 2018 IBM Corp. and others + * Copyright (c) 2004, 2022 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -715,7 +715,10 @@ private void buildAddressSpace(Builder builder, int asid, boolean is64Bit) { builder.setExecutableUnavailable("unable to extract executable information"); //System.out.println("Bad EDB "+edb); } - String commandLine = environment.getProperty("IBM_JAVA_COMMAND_LINE", ""); + String commandLine = environment.getProperty("OPENJ9_JAVA_COMMAND_LINE", null); + if (commandLine == null) { + commandLine = environment.getProperty("IBM_JAVA_COMMAND_LINE", ""); + } //Use the EDB address for the process id, if available, otherwise use the Address space id. String pid = edb != null ? format(edb.address()) : format(asid); if (null != _j9rasReader) { diff --git a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/j9/ImageProcess.java b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/j9/ImageProcess.java index f5da626d95b..6341a321b77 100644 --- a/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/j9/ImageProcess.java +++ b/jcl/src/openj9.dtfj/share/classes/com/ibm/dtfj/image/j9/ImageProcess.java @@ -1,6 +1,6 @@ /*[INCLUDE-IF Sidecar18-SE]*/ /******************************************************************************* - * Copyright (c) 2004, 2017 IBM Corp. and others + * Copyright (c) 2004, 2022 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -50,9 +50,9 @@ public class ImageProcess implements com.ibm.dtfj.image.ImageProcess private long _faultingNativeID = 0; //the ID of the native thread which caused the GPF (if there was one) private int _signalNumber = 0; private Exception _runtimeCheckFailure; - private static final String JAVA_COMMAND_LINE_ENVIRONMENT_VARIABLE = "IBM_JAVA_COMMAND_LINE"; - - + private static final String JAVA_COMMAND_LINE_ENVIRONMENT_VARIABLE = "OPENJ9_JAVA_COMMAND_LINE"; + private static final String LEGACY_JAVA_COMMAND_LINE_ENVIRONMENT_VARIABLE = "IBM_JAVA_COMMAND_LINE"; + public ImageProcess(String pid, String commandLine, Properties environment, ImageThread currentThread, Iterator threads, ImageModule executable, Iterator libraries, int pointerSize) { _id = pid; @@ -77,10 +77,17 @@ public String getCommandLine() throws DataUnavailable, CorruptDataException // all platforms we now try that first, with the core reader as a fallback. Properties environment = getEnvironment(); String javaCommandLine = environment.getProperty(JAVA_COMMAND_LINE_ENVIRONMENT_VARIABLE); - + if (javaCommandLine != null) { return javaCommandLine; } + + javaCommandLine = environment.getProperty(LEGACY_JAVA_COMMAND_LINE_ENVIRONMENT_VARIABLE); + + if (javaCommandLine != null) { + return javaCommandLine; + } + if (_commandLine == null) { throw new DataUnavailable("Command line unavailable from core dump"); } diff --git a/runtime/j9vm/jvm.c b/runtime/j9vm/jvm.c index 417d322daed..bd1233613ff 100644 --- a/runtime/j9vm/jvm.c +++ b/runtime/j9vm/jvm.c @@ -68,6 +68,10 @@ #include "jitserver_error.h" #endif /* J9VM_OPT_JITSERVER */ +#if defined(WIN32) +#include +#include +#endif /* defined(WIN32) */ /* Must include this after j9vm_internal.h */ #include @@ -452,6 +456,72 @@ static const J9SignalMapping signalMap[] = { {NULL, J9_SIG_ERR} }; +static void +captureCommandLine(void) +{ +#if defined(WIN32) +#define ENV_VAR_NAME L"OPENJ9_JAVA_COMMAND_LINE" +#else /* defined(WIN32) */ +#define ENV_VAR_NAME "OPENJ9_JAVA_COMMAND_LINE" +#endif /* defined(WIN32) */ + +#if defined(LINUX) + int fd = open("/proc/self/cmdline", O_RDONLY, 0); + + if (fd >= 0) { + char *buffer = NULL; + size_t length = 0; + for (;;) { + char small_buffer[512]; + ssize_t count = read(fd, small_buffer, sizeof(small_buffer)); + if (count <= 0) { + break; + } + length += (size_t)count; + } + if (length < 2) { + goto done; + } + /* final NUL is already included in length */ + buffer = malloc(length); + if (NULL == buffer) { + goto done; + } + if ((off_t)-1 == lseek(fd, 0, SEEK_SET)) { + goto done; + } + if (read(fd, buffer, length) != length) { + goto done; + } + /* replace the internal NULs with spaces */ + for (length -= 2;; length -= 1) { + if (0 == length) { + break; + } + if ('\0' == buffer[length]) { + buffer[length] = ' '; + } + } + /* it's not fatal if setenv() fails, so don't bother checking */ + setenv(ENV_VAR_NAME, buffer, 1 /* overwrite */); +done: + if (NULL != buffer) { + free(buffer); + } + close(fd); + } +#elif defined(WIN32) /* defined(LINUX) */ + const wchar_t *commandLine = GetCommandLineW(); + + if (NULL != commandLine) { + /* it's not fatal if _wputenv_s() fails, so don't bother checking */ + _wputenv_s(ENV_VAR_NAME, commandLine); + } +#endif /* defined(LINUX) */ + +#undef ENV_VAR_NAME +} + static void freeGlobals(void) { free(newPath); @@ -1657,6 +1727,7 @@ JNI_CreateJavaVM_impl(JavaVM **pvm, void **penv, void *vm_args, BOOLEAN isJITSer return JNI_ERR; } #endif /* defined(J9ZTPF) */ + captureCommandLine(); /* * Linux uses LD_LIBRARY_PATH * z/OS uses LIBPATH diff --git a/runtime/rasdump/javadump.cpp b/runtime/rasdump/javadump.cpp index 9d8ec151ca2..8bb5ba80307 100644 --- a/runtime/rasdump/javadump.cpp +++ b/runtime/rasdump/javadump.cpp @@ -1138,7 +1138,7 @@ JavaCoreDumpWriter::writeEnvironmentSection(void) /* Write the command line data */ char commandLineBuffer[_MaximumCommandLineLength]; - IDATA result = j9sysinfo_get_env("IBM_JAVA_COMMAND_LINE", commandLineBuffer, _MaximumCommandLineLength); + IDATA result = j9sysinfo_get_env("OPENJ9_JAVA_COMMAND_LINE", commandLineBuffer, _MaximumCommandLineLength); if (0 == result) { /* Ensure null-terminated */ @@ -1152,7 +1152,7 @@ JavaCoreDumpWriter::writeEnvironmentSection(void) char *longCommandLineBuffer = (char *)j9mem_allocate_memory(result, OMRMEM_CATEGORY_VM); if (NULL != longCommandLineBuffer) { - if (j9sysinfo_get_env("IBM_JAVA_COMMAND_LINE", longCommandLineBuffer, result) == 0) { + if (j9sysinfo_get_env("OPENJ9_JAVA_COMMAND_LINE", longCommandLineBuffer, result) == 0) { longCommandLineBuffer[result - 1] = '\0'; _OutputStream.writeCharacters("1CICMDLINE "); _OutputStream.writeCharacters(longCommandLineBuffer);