8275375: [REDO] JDK-8271949 dumppath in -XX:FlightRecorderOptions does not affect
Reviewed-by: egahlin, mgronlun
This commit is contained in:
parent
24877ac078
commit
07669e3bc6
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2021, 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
|
||||
@ -35,6 +35,7 @@
|
||||
#include "jfr/recorder/repository/jfrRepository.hpp"
|
||||
#include "jfr/recorder/repository/jfrChunkRotation.hpp"
|
||||
#include "jfr/recorder/repository/jfrChunkWriter.hpp"
|
||||
#include "jfr/recorder/repository/jfrEmergencyDump.hpp"
|
||||
#include "jfr/recorder/service/jfrEventThrottler.hpp"
|
||||
#include "jfr/recorder/service/jfrOptionSet.hpp"
|
||||
#include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
|
||||
@ -315,6 +316,20 @@ JVM_ENTRY_NO_ENV(void, jfr_set_repository_location(JNIEnv* env, jobject repo, js
|
||||
return JfrRepository::set_path(location, thread);
|
||||
JVM_END
|
||||
|
||||
NO_TRANSITION(void, jfr_set_dump_path(JNIEnv* env, jobject jvm, jstring dumppath))
|
||||
if (dumppath == NULL) {
|
||||
JfrEmergencyDump::set_dump_path(NULL);
|
||||
} else {
|
||||
const char* dump_path = env->GetStringUTFChars(dumppath, NULL);
|
||||
JfrEmergencyDump::set_dump_path(dump_path);
|
||||
env->ReleaseStringUTFChars(dumppath, dump_path);
|
||||
}
|
||||
NO_TRANSITION_END
|
||||
|
||||
NO_TRANSITION(jstring, jfr_get_dump_path(JNIEnv* env, jobject jvm))
|
||||
return env->NewStringUTF(JfrEmergencyDump::get_dump_path());
|
||||
NO_TRANSITION_END
|
||||
|
||||
JVM_ENTRY_NO_ENV(void, jfr_uncaught_exception(JNIEnv* env, jobject jvm, jobject t, jthrowable throwable))
|
||||
JfrJavaSupport::uncaught_exception(throwable, thread);
|
||||
JVM_END
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2021, 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
|
||||
@ -113,6 +113,10 @@ jlong JNICALL jfr_type_id(JNIEnv* env, jobject jvm, jclass jc);
|
||||
|
||||
void JNICALL jfr_set_repository_location(JNIEnv* env, jobject repo, jstring location);
|
||||
|
||||
void JNICALL jfr_set_dump_path(JNIEnv* env, jobject jvm, jstring dumppath);
|
||||
|
||||
jstring JNICALL jfr_get_dump_path(JNIEnv* env, jobject jvm);
|
||||
|
||||
jobject JNICALL jfr_get_event_writer(JNIEnv* env, jclass cls);
|
||||
|
||||
jobject JNICALL jfr_new_event_writer(JNIEnv* env, jclass cls);
|
||||
|
@ -75,6 +75,8 @@ JfrJniMethodRegistration::JfrJniMethodRegistration(JNIEnv* env) {
|
||||
(char*)"flush", (char*)"(Ljdk/jfr/internal/EventWriter;II)Z", (void*)jfr_event_writer_flush,
|
||||
(char*)"flush", (char*)"()V", (void*)jfr_flush,
|
||||
(char*)"setRepositoryLocation", (char*)"(Ljava/lang/String;)V", (void*)jfr_set_repository_location,
|
||||
(char*)"setDumpPath", (char*)"(Ljava/lang/String;)V", (void*)jfr_set_dump_path,
|
||||
(char*)"getDumpPath", (char*)"()Ljava/lang/String;", (void*)jfr_get_dump_path,
|
||||
(char*)"abort", (char*)"(Ljava/lang/String;)V", (void*)jfr_abort,
|
||||
(char*)"addStringConstant", (char*)"(JLjava/lang/String;)Z", (void*)jfr_add_string_constant,
|
||||
(char*)"uncaughtException", (char*)"(Ljava/lang/Thread;Ljava/lang/Throwable;)V", (void*)jfr_uncaught_exception,
|
||||
|
@ -41,6 +41,8 @@
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
|
||||
char JfrEmergencyDump::_dump_path[JVM_MAXPATHLEN] = { 0 };
|
||||
|
||||
static const char vm_error_filename_fmt[] = "hs_err_pid%p.jfr";
|
||||
static const char vm_oom_filename_fmt[] = "hs_oom_pid%p.jfr";
|
||||
static const char vm_soe_filename_fmt[] = "hs_soe_pid%p.jfr";
|
||||
@ -66,12 +68,17 @@ static bool is_path_empty() {
|
||||
}
|
||||
|
||||
// returns with an appended file separator (if successful)
|
||||
static size_t get_current_directory() {
|
||||
if (os::get_current_directory(_path_buffer, sizeof(_path_buffer)) == NULL) {
|
||||
return 0;
|
||||
static size_t get_dump_directory() {
|
||||
const char* dump_path = JfrEmergencyDump::get_dump_path();
|
||||
if (*dump_path == '\0') {
|
||||
if (os::get_current_directory(_path_buffer, sizeof(_path_buffer)) == NULL) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
strcpy(_path_buffer, dump_path);
|
||||
}
|
||||
const size_t cwd_len = strlen(_path_buffer);
|
||||
const int result = jio_snprintf(_path_buffer + cwd_len,
|
||||
const size_t path_len = strlen(_path_buffer);
|
||||
const int result = jio_snprintf(_path_buffer + path_len,
|
||||
sizeof(_path_buffer),
|
||||
"%s",
|
||||
os::file_separator());
|
||||
@ -105,7 +112,7 @@ static void close_emergency_dump_file() {
|
||||
static const char* create_emergency_dump_path() {
|
||||
assert(is_path_empty(), "invariant");
|
||||
|
||||
const size_t path_len = get_current_directory();
|
||||
const size_t path_len = get_dump_directory();
|
||||
if (path_len == 0) {
|
||||
return NULL;
|
||||
}
|
||||
@ -125,12 +132,21 @@ static const char* create_emergency_dump_path() {
|
||||
return result ? _path_buffer : NULL;
|
||||
}
|
||||
|
||||
static bool open_emergency_dump_file() {
|
||||
bool JfrEmergencyDump::open_emergency_dump_file() {
|
||||
if (is_emergency_dump_file_open()) {
|
||||
// opened already
|
||||
return true;
|
||||
}
|
||||
return open_emergency_dump_fd(create_emergency_dump_path());
|
||||
|
||||
bool result = open_emergency_dump_fd(create_emergency_dump_path());
|
||||
if (!result && *_dump_path != '\0') {
|
||||
log_warning(jfr)("Unable to create an emergency dump file at the location set by dumppath=%s", _dump_path);
|
||||
// Fallback. Try to create it in the current directory.
|
||||
*_dump_path = '\0';
|
||||
*_path_buffer = '\0';
|
||||
result = open_emergency_dump_fd(create_emergency_dump_path());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void report(outputStream* st, bool emergency_file_opened, const char* repository_path) {
|
||||
@ -150,6 +166,21 @@ static void report(outputStream* st, bool emergency_file_opened, const char* rep
|
||||
}
|
||||
}
|
||||
|
||||
void JfrEmergencyDump::set_dump_path(const char* dump_path) {
|
||||
if (dump_path == NULL || *dump_path == '\0') {
|
||||
os::get_current_directory(_dump_path, sizeof(_dump_path));
|
||||
} else {
|
||||
if (strlen(dump_path) < JVM_MAXPATHLEN) {
|
||||
strncpy(_dump_path, dump_path, JVM_MAXPATHLEN);
|
||||
_dump_path[JVM_MAXPATHLEN - 1] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* JfrEmergencyDump::get_dump_path() {
|
||||
return _dump_path;
|
||||
}
|
||||
|
||||
void JfrEmergencyDump::on_vm_error_report(outputStream* st, const char* repository_path) {
|
||||
assert(st != NULL, "invariant");
|
||||
Thread* thread = Thread::current_or_null_safe();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2021, 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
|
||||
@ -32,7 +32,14 @@
|
||||
// Responsible for creating an hs_err<pid>.jfr file in exceptional shutdown situations (crash, OOM)
|
||||
//
|
||||
class JfrEmergencyDump : AllStatic {
|
||||
private:
|
||||
static char _dump_path[JVM_MAXPATHLEN];
|
||||
|
||||
static bool open_emergency_dump_file();
|
||||
|
||||
public:
|
||||
static void set_dump_path(const char* dump_path);
|
||||
static const char* get_dump_path();
|
||||
static const char* chunk_path(const char* repository_path);
|
||||
static void on_vm_error(const char* repository_path);
|
||||
static void on_vm_error_report(outputStream* st, const char* repository_path);
|
||||
|
@ -163,6 +163,7 @@ bool JfrOptionSet::allow_event_retransforms() {
|
||||
|
||||
// default options for the dcmd parser
|
||||
const char* const default_repository = NULL;
|
||||
const char* const default_dumppath = NULL;
|
||||
const char* const default_global_buffer_size = "512k";
|
||||
const char* const default_num_global_buffers = "20";
|
||||
const char* const default_memory_size = "10m";
|
||||
@ -182,6 +183,13 @@ static DCmdArgument<char*> _dcmd_repository(
|
||||
false,
|
||||
default_repository);
|
||||
|
||||
static DCmdArgument<char*> _dcmd_dumppath(
|
||||
"dumppath",
|
||||
"Path to emergency dump",
|
||||
"STRING",
|
||||
false,
|
||||
default_dumppath);
|
||||
|
||||
static DCmdArgument<MemorySizeArgument> _dcmd_threadbuffersize(
|
||||
"threadbuffersize",
|
||||
"Thread buffer size",
|
||||
@ -258,6 +266,7 @@ static DCmdParser _parser;
|
||||
|
||||
static void register_parser_options() {
|
||||
_parser.add_dcmd_option(&_dcmd_repository);
|
||||
_parser.add_dcmd_option(&_dcmd_dumppath);
|
||||
_parser.add_dcmd_option(&_dcmd_threadbuffersize);
|
||||
_parser.add_dcmd_option(&_dcmd_memorysize);
|
||||
_parser.add_dcmd_option(&_dcmd_globalbuffersize);
|
||||
@ -346,6 +355,18 @@ bool JfrOptionSet::configure(TRAPS) {
|
||||
configure._repository_path.set_value(repo_copy);
|
||||
}
|
||||
|
||||
configure._dump_path.set_is_set(_dcmd_dumppath.is_set());
|
||||
char* dumppath = _dcmd_dumppath.value();
|
||||
if (dumppath != NULL) {
|
||||
const size_t len = strlen(dumppath);
|
||||
char* dumppath_copy = JfrCHeapObj::new_array<char>(len + 1);
|
||||
if (NULL == dumppath_copy) {
|
||||
return false;
|
||||
}
|
||||
strncpy(dumppath_copy, dumppath, len + 1);
|
||||
configure._dump_path.set_value(dumppath_copy);
|
||||
}
|
||||
|
||||
configure._stack_depth.set_is_set(_dcmd_stackdepth.is_set());
|
||||
configure._stack_depth.set_value(_dcmd_stackdepth.value());
|
||||
|
||||
@ -373,6 +394,7 @@ bool JfrOptionSet::configure(TRAPS) {
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
java_lang_Throwable::print(PENDING_EXCEPTION, tty);
|
||||
CLEAR_PENDING_EXCEPTION;
|
||||
tty->cr(); // java_lang_Throwable::print will not print '\n'
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -473,13 +473,26 @@ public final class JVM {
|
||||
public native void flush();
|
||||
|
||||
/**
|
||||
* Sets the location of the disk repository, to be used at an emergency
|
||||
* dump.
|
||||
* Sets the location of the disk repository.
|
||||
*
|
||||
* @param dirText
|
||||
*/
|
||||
public native void setRepositoryLocation(String dirText);
|
||||
|
||||
/**
|
||||
* Sets the path to emergency dump.
|
||||
*
|
||||
* @param dumpPathText
|
||||
*/
|
||||
public native void setDumpPath(String dumpPathText);
|
||||
|
||||
/**
|
||||
* Gets the path to emergency dump.
|
||||
*
|
||||
* @return The path to emergency dump.
|
||||
*/
|
||||
public native String getDumpPath();
|
||||
|
||||
/**
|
||||
* Access to VM termination support.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2021, 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
|
||||
@ -25,9 +25,16 @@
|
||||
|
||||
package jdk.jfr.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import jdk.jfr.internal.LogLevel;
|
||||
import jdk.jfr.internal.LogTag;
|
||||
import jdk.jfr.internal.Logger;
|
||||
import jdk.jfr.internal.SecuritySupport.SafePath;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
import static java.nio.file.LinkOption.*;
|
||||
|
||||
/**
|
||||
* Options that control Flight Recorder.
|
||||
*
|
||||
@ -48,7 +55,7 @@ public final class Options {
|
||||
private static final int DEFAULT_STACK_DEPTH = 64;
|
||||
private static final boolean DEFAULT_SAMPLE_THREADS = true;
|
||||
private static final long DEFAULT_MAX_CHUNK_SIZE = 12 * 1024 * 1024;
|
||||
private static final SafePath DEFAULT_DUMP_PATH = SecuritySupport.USER_HOME;
|
||||
private static final SafePath DEFAULT_DUMP_PATH = null;
|
||||
|
||||
private static long memorySize;
|
||||
private static long globalBufferSize;
|
||||
@ -57,7 +64,6 @@ public final class Options {
|
||||
private static int stackDepth;
|
||||
private static boolean sampleThreads;
|
||||
private static long maxChunkSize;
|
||||
private static SafePath dumpPath;
|
||||
|
||||
static {
|
||||
final long pageSize = Unsafe.getUnsafe().pageSize();
|
||||
@ -113,12 +119,19 @@ public final class Options {
|
||||
globalBufferSize = globalBufsize;
|
||||
}
|
||||
|
||||
public static synchronized void setDumpPath(SafePath path) {
|
||||
dumpPath = path;
|
||||
public static synchronized void setDumpPath(SafePath path) throws IOException {
|
||||
if (path != null) {
|
||||
if (SecuritySupport.isWritable(path)) {
|
||||
path = SecuritySupport.toRealPath(path, NOFOLLOW_LINKS);
|
||||
} else {
|
||||
throw new IOException("Cannot write JFR emergency dump to " + path.toString());
|
||||
}
|
||||
}
|
||||
jvm.setDumpPath(path == null ? null : path.toString());
|
||||
}
|
||||
|
||||
public static synchronized SafePath getDumpPath() {
|
||||
return dumpPath;
|
||||
return new SafePath(jvm.getDumpPath());
|
||||
}
|
||||
|
||||
public static synchronized void setStackDepth(Integer stackTraceDepth) {
|
||||
@ -144,7 +157,11 @@ public final class Options {
|
||||
setMemorySize(DEFAULT_MEMORY_SIZE);
|
||||
setGlobalBufferSize(DEFAULT_GLOBAL_BUFFER_SIZE);
|
||||
setGlobalBufferCount(DEFAULT_GLOBAL_BUFFER_COUNT);
|
||||
setDumpPath(DEFAULT_DUMP_PATH);
|
||||
try {
|
||||
setDumpPath(DEFAULT_DUMP_PATH);
|
||||
} catch (IOException e) {
|
||||
// Ignore (depends on default value in JVM: it would be NULL)
|
||||
}
|
||||
setSampleThreads(DEFAULT_SAMPLE_THREADS);
|
||||
setStackDepth(DEFAULT_STACK_DEPTH);
|
||||
setThreadBufferSize(DEFAULT_THREAD_BUFFER_SIZE);
|
||||
|
@ -41,6 +41,7 @@ import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.LinkOption;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
@ -77,7 +78,6 @@ public final class SecuritySupport {
|
||||
private static final Module JFR_MODULE = Event.class.getModule();
|
||||
public static final SafePath JFC_DIRECTORY = getPathInProperty("java.home", "lib/jfr");
|
||||
public static final FileAccess PRIVILEGED = new Privileged();
|
||||
static final SafePath USER_HOME = getPathInProperty("user.home", null);
|
||||
static final SafePath JAVA_IO_TMPDIR = getPathInProperty("java.io.tmpdir", null);
|
||||
|
||||
static {
|
||||
@ -365,8 +365,8 @@ public final class SecuritySupport {
|
||||
doPriviligedIO(() -> Files.walkFileTree(safePath.toPath(), new DirectoryCleaner()));
|
||||
}
|
||||
|
||||
static SafePath toRealPath(SafePath safePath) throws IOException {
|
||||
return new SafePath(doPrivilegedIOWithReturn(() -> safePath.toPath().toRealPath()));
|
||||
static SafePath toRealPath(SafePath safePath, LinkOption... options) throws IOException {
|
||||
return new SafePath(doPrivilegedIOWithReturn(() -> safePath.toPath().toRealPath(options)));
|
||||
}
|
||||
|
||||
static boolean existDirectory(SafePath directory) throws IOException {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2021, 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
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
package jdk.jfr.internal.dcmd;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import jdk.jfr.FlightRecorder;
|
||||
import jdk.jfr.internal.LogLevel;
|
||||
@ -106,7 +106,11 @@ final class DCmdConfigure extends AbstractDCmd {
|
||||
}
|
||||
|
||||
if (dumpPath != null) {
|
||||
Options.setDumpPath(new SafePath(dumpPath));
|
||||
try {
|
||||
Options.setDumpPath(new SafePath(dumpPath));
|
||||
} catch (IOException e) {
|
||||
throw new DCmdException("Could not set " + dumpPath + " to emergency dump path. " + e.getMessage(), e);
|
||||
}
|
||||
Logger.log(LogTag.JFR, LogLevel.INFO, "Emergency dump path set to " + dumpPath);
|
||||
if (verbose) {
|
||||
printDumpPath();
|
||||
@ -183,6 +187,7 @@ final class DCmdConfigure extends AbstractDCmd {
|
||||
println("Current configuration:");
|
||||
println();
|
||||
printRepositoryPath();
|
||||
printDumpPath();
|
||||
printStackDepth();
|
||||
printGlobalBufferCount();
|
||||
printGlobalBufferSize();
|
||||
|
@ -26,6 +26,7 @@ import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import jdk.internal.misc.Unsafe;
|
||||
@ -74,22 +75,42 @@ public class TestDumpOnCrash {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// Test without dumppath
|
||||
test(CrasherIllegalAccess.class, "", true);
|
||||
test(CrasherIllegalAccess.class, "", false);
|
||||
test(CrasherHalt.class, "", true);
|
||||
test(CrasherHalt.class, "", false);
|
||||
|
||||
// Test with dumppath
|
||||
Path dumppath = Files.createTempDirectory(null);
|
||||
try {
|
||||
test(CrasherIllegalAccess.class, "", true, dumppath.toString());
|
||||
test(CrasherIllegalAccess.class, "", false, dumppath.toString());
|
||||
test(CrasherHalt.class, "", true, dumppath.toString());
|
||||
test(CrasherHalt.class, "", false, dumppath.toString());
|
||||
} finally {
|
||||
dumppath.toFile().delete();
|
||||
}
|
||||
|
||||
// Test is excluded until 8219680 is fixed
|
||||
// @ignore 8219680
|
||||
// test(CrasherSig.class, "FPE", true);
|
||||
}
|
||||
|
||||
private static void test(Class<?> crasher, String signal, boolean disk) throws Exception {
|
||||
test(crasher, signal, disk, null);
|
||||
}
|
||||
|
||||
private static void test(Class<?> crasher, String signal, boolean disk, String dumppath) throws Exception {
|
||||
test(crasher, signal, disk, dumppath, dumppath);
|
||||
}
|
||||
|
||||
private static void test(Class<?> crasher, String signal, boolean disk, String dumppath, String expectedPath) throws Exception {
|
||||
// The JVM may be in a state it can't recover from, so try three times
|
||||
// before concluding functionality is not working.
|
||||
for (int attempt = 0; attempt < ATTEMPTS; attempt++) {
|
||||
try {
|
||||
verify(runProcess(crasher, signal, disk));
|
||||
verify(runProcess(crasher, signal, disk, dumppath), expectedPath);
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
System.out.println("Attempt " + attempt + ". Verification failed:");
|
||||
@ -105,17 +126,19 @@ public class TestDumpOnCrash {
|
||||
throw new Exception(ATTEMPTS + " attempts with failure!");
|
||||
}
|
||||
|
||||
private static long runProcess(Class<?> crasher, String signal, boolean disk) throws Exception {
|
||||
private static long runProcess(Class<?> crasher, String signal, boolean disk, String dumppath) throws Exception {
|
||||
System.out.println("Test case for crasher " + crasher.getName());
|
||||
final String flightRecordingOptions = "dumponexit=true,disk=" + Boolean.toString(disk);
|
||||
Process p = ProcessTools.createTestJvm(
|
||||
"-Xmx64m",
|
||||
"-XX:-CreateCoredumpOnCrash",
|
||||
"--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED",
|
||||
"-XX:StartFlightRecording:" + flightRecordingOptions,
|
||||
crasher.getName(),
|
||||
signal)
|
||||
.start();
|
||||
List<String> options = new ArrayList<>();
|
||||
options.add("-Xmx64m");
|
||||
options.add("-XX:-CreateCoredumpOnCrash");
|
||||
options.add("--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED");
|
||||
options.add("-XX:StartFlightRecording:dumponexit=true,disk=" + Boolean.toString(disk));
|
||||
if (dumppath != null) {
|
||||
options.add("-XX:FlightRecorderOptions=dumppath=" + dumppath);
|
||||
}
|
||||
options.add(crasher.getName());
|
||||
options.add(signal);
|
||||
Process p = ProcessTools.createTestJvm(options).start();
|
||||
|
||||
OutputAnalyzer output = new OutputAnalyzer(p);
|
||||
System.out.println("========== Crasher process output:");
|
||||
@ -125,9 +148,10 @@ public class TestDumpOnCrash {
|
||||
return p.pid();
|
||||
}
|
||||
|
||||
private static void verify(long pid) throws IOException {
|
||||
private static void verify(long pid, String dumppath) throws IOException {
|
||||
String fileName = "hs_err_pid" + pid + ".jfr";
|
||||
Path file = Paths.get(fileName).toAbsolutePath().normalize();
|
||||
Path file = (dumppath == null) ? Paths.get(fileName) : Paths.get(dumppath, fileName);
|
||||
file = file.toAbsolutePath().normalize();
|
||||
|
||||
Asserts.assertTrue(Files.exists(file), "No emergency jfr recording file " + file + " exists");
|
||||
Asserts.assertNotEquals(Files.size(file), 0L, "File length 0. Should at least be some bytes");
|
||||
|
Loading…
Reference in New Issue
Block a user