Skip to content

Commit

Permalink
Capture command line in environment on Linux and Windows
Browse files Browse the repository at this point in the history
* use OPENJ9_JAVA_COMMAND_LINE, but recognize IBM_JAVA_COMMAND_LINE
* overwrite any existing definition

Signed-off-by: Keith W. Campbell <[email protected]>
  • Loading branch information
keithc-ca committed Feb 16, 2022
1 parent 2211e64 commit 229e47c
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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<ISymbol> environSymbols = getEnvironmentSymbols();
ISymbol environ = null;

if (0 == environSymbols.size()) {
List<ISymbol> 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"
*
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 <executable> 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);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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");
}
Expand Down
71 changes: 71 additions & 0 deletions runtime/j9vm/jvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@
#include "jitserver_error.h"
#endif /* J9VM_OPT_JITSERVER */

#if defined(WIN32)
#include <processenv.h>
#include <stdlib.h>
#endif /* defined(WIN32) */

/* Must include this after j9vm_internal.h */
#include <string.h>
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions runtime/rasdump/javadump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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);
Expand Down

0 comments on commit 229e47c

Please sign in to comment.