Skip to content

Commit 377fc8b

Browse files
committed
JFR dump to Jcmd current working directory by default
If the filename supplied is not an absolute path, Jcmd current work directory is used instead of the target VM location; Throw an error if the duration option doesn't have any time unit. Signed-off-by: Jason Feng <[email protected]>
1 parent 2852782 commit 377fc8b

File tree

1 file changed

+57
-4
lines changed

1 file changed

+57
-4
lines changed

Diff for: jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/DiagnosticUtils.java

+57-4
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@
2323

2424
package openj9.internal.tools.attach.target;
2525

26+
import java.io.File;
2627
import java.io.PrintWriter;
2728
import java.io.StringWriter;
29+
import java.nio.file.InvalidPathException;
30+
import java.nio.file.Path;
31+
import java.nio.file.Paths;
2832
import java.util.Arrays;
2933
import java.util.HashMap;
3034
import java.util.Map;
@@ -144,6 +148,9 @@ public class DiagnosticUtils {
144148
private static final String DIAGNOSTICS_JFR_START = "JFR.start";
145149
private static final String DIAGNOSTICS_JFR_DUMP = "JFR.dump";
146150
private static final String DIAGNOSTICS_JFR_STOP = "JFR.stop";
151+
152+
private static final int ERROR_NO_TIME_UNIT = -1;
153+
private static final int ERROR_NO_TIME_DURATION = -2;
147154
/*[ENDIF] JFR_SUPPORT */
148155

149156
/**
@@ -209,7 +216,39 @@ public static String makeThreadPrintCommand(boolean lockedSynchronizers) {
209216
* @return formatted string
210217
*/
211218
public static String makeJcmdCommand(String[] options, int skip) {
212-
String cmd = String.join(DIAGNOSTICS_OPTION_SEPARATOR, Arrays.asList(options).subList(skip, options.length));
219+
int optionsLength = options.length;
220+
/*[IF JFR_SUPPORT]*/
221+
if (optionsLength >= 2) {
222+
// there is a jcmd command
223+
if (DIAGNOSTICS_JFR_START.equalsIgnoreCase(options[1])) {
224+
// search JFR.start options
225+
for (int i = 2; i < optionsLength; i++) {
226+
String option = options[i];
227+
IPC.logMessage("makeJcmdCommand: option = ", option);
228+
if (option.startsWith("filename=")) {
229+
String fileName = option.substring(option.indexOf("=") + 1);
230+
try {
231+
Path filePath = Paths.get(fileName);
232+
if (!filePath.isAbsolute()) {
233+
// default recording file path is jcmd current working directory
234+
String jcmdPWD = Paths.get("").toAbsolutePath().toString();
235+
fileName = jcmdPWD + File.separator + fileName;
236+
IPC.logMessage("makeJcmdCommand: absolute filename = ", fileName);
237+
// replace existing entry with an absolute jcmd pwd path for the target VM
238+
options[i] = "filename=" + fileName;
239+
}
240+
} catch (InvalidPathException ipe) {
241+
// ignore this exception and keep the original entry
242+
IPC.logMessage("makeJcmdCommand: ipe = ", ipe.getMessage());
243+
}
244+
// only one filename is allowed
245+
break;
246+
}
247+
}
248+
}
249+
}
250+
/*[ENDIF] JFR_SUPPORT */
251+
String cmd = String.join(DIAGNOSTICS_OPTION_SEPARATOR, Arrays.asList(options).subList(skip, optionsLength));
213252
return cmd;
214253
}
215254

@@ -415,13 +454,25 @@ private static long convertToMilliseconds(String timeValue) {
415454
timeInMilli = TimeUnit.DAYS.toMillis(time);
416455
break;
417456
default:
418-
// no unit or unrecognized unit, assume milliseconds
419-
timeInMilli = time;
457+
// no unit or unrecognized unit, return ERROR_NO_TIME_UNIT
458+
timeInMilli = ERROR_NO_TIME_UNIT;
420459
break;
421460
}
422461
return timeInMilli;
423462
}
424463

464+
/**
465+
* Parse a time parameter, and return the duration in milliseconds.
466+
* If the time unit is missing, ERROR_NO_TIME_UNIT is returned.
467+
* If the paramName is not in parameters, ERROR_NO_TIME_DURATION is returned.
468+
*
469+
* @param paramName the parameter name
470+
* @param parameters the parameter array
471+
*
472+
* @return the duration in milliseconds,
473+
* ERROR_NO_TIME_UNIT if no time unit,
474+
* ERROR_NO_TIME_DURATION if paramName wasn't found.
475+
*/
425476
private static long parseTimeParameter(String paramName, String[] parameters) {
426477
for (String param : parameters) {
427478
if (param.startsWith(paramName + "=")) {
@@ -431,7 +482,7 @@ private static long parseTimeParameter(String paramName, String[] parameters) {
431482
}
432483
}
433484
}
434-
return -1;
485+
return ERROR_NO_TIME_DURATION;
435486
}
436487

437488
private static String parseStringParameter(String paramName, String[] parameters, String defaultValue) {
@@ -488,6 +539,8 @@ public void run() {
488539
}
489540
};
490541
timer.schedule(jfrDumpTask, duration);
542+
} if (duration == ERROR_NO_TIME_UNIT) {
543+
return DiagnosticProperties.makeErrorProperties("The duration doesn't have a time unit.");
491544
} else {
492545
// the recording is on until JFR.stop
493546
}

0 commit comments

Comments
 (0)