Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Capture command line in environment on Linux and Windows #14520

Merged
merged 1 commit into from
Feb 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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:
pshipton marked this conversation as resolved.
Show resolved Hide resolved
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