8260296: SA's dumpreplaydata fails
Reviewed-by: kvn, cjplummer, iignatyev
This commit is contained in:
parent
07918995da
commit
3495febf51
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -27,6 +27,9 @@
|
|||||||
#include "ci/ciUtilities.inline.hpp"
|
#include "ci/ciUtilities.inline.hpp"
|
||||||
#include "gc/shared/collectedHeap.inline.hpp"
|
#include "gc/shared/collectedHeap.inline.hpp"
|
||||||
|
|
||||||
|
// Not inlined to preserve visibility of ciMetaData vtable symbol. Required by SA.
|
||||||
|
bool ciMetadata::is_classless() const { return false; }
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
// ciMetadata::print
|
// ciMetadata::print
|
||||||
//
|
//
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -43,7 +43,7 @@ class ciMetadata: public ciBaseObject {
|
|||||||
ciMetadata(): _metadata(NULL) {}
|
ciMetadata(): _metadata(NULL) {}
|
||||||
ciMetadata(Metadata* o): _metadata(o) {}
|
ciMetadata(Metadata* o): _metadata(o) {}
|
||||||
|
|
||||||
virtual bool is_classless() const { return false; }
|
virtual bool is_classless() const;
|
||||||
public:
|
public:
|
||||||
bool is_loaded() const { return _metadata != NULL || is_classless(); }
|
bool is_loaded() const { return _metadata != NULL || is_classless(); }
|
||||||
|
|
||||||
|
@ -1256,7 +1256,7 @@ void MethodData::initialize() {
|
|||||||
object_size += extra_size + arg_data_size;
|
object_size += extra_size + arg_data_size;
|
||||||
|
|
||||||
int parms_cell = ParametersTypeData::compute_cell_count(method());
|
int parms_cell = ParametersTypeData::compute_cell_count(method());
|
||||||
// If we are profiling parameters, we reserver an area near the end
|
// If we are profiling parameters, we reserved an area near the end
|
||||||
// of the MDO after the slots for bytecodes (because there's no bci
|
// of the MDO after the slots for bytecodes (because there's no bci
|
||||||
// for method entry so they don't fit with the framework for the
|
// for method entry so they don't fit with the framework for the
|
||||||
// profiling of bytecodes). We store the offset within the MDO of
|
// profiling of bytecodes). We store the offset within the MDO of
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -30,6 +30,7 @@ import sun.jvm.hotspot.debugger.*;
|
|||||||
import sun.jvm.hotspot.runtime.*;
|
import sun.jvm.hotspot.runtime.*;
|
||||||
import sun.jvm.hotspot.oops.*;
|
import sun.jvm.hotspot.oops.*;
|
||||||
import sun.jvm.hotspot.types.*;
|
import sun.jvm.hotspot.types.*;
|
||||||
|
import sun.jvm.hotspot.types.Field;
|
||||||
import sun.jvm.hotspot.utilities.Observable;
|
import sun.jvm.hotspot.utilities.Observable;
|
||||||
import sun.jvm.hotspot.utilities.Observer;
|
import sun.jvm.hotspot.utilities.Observer;
|
||||||
|
|
||||||
@ -44,7 +45,7 @@ public class ciMethodData extends ciMetadata implements MethodDataInterface<ciKl
|
|||||||
|
|
||||||
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
|
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
|
||||||
Type type = db.lookupType("ciMethodData");
|
Type type = db.lookupType("ciMethodData");
|
||||||
origField = type.getAddressField("_orig");
|
origField = type.getField("_orig");
|
||||||
currentMileageField = new CIntField(type.getCIntegerField("_current_mileage"), 0);
|
currentMileageField = new CIntField(type.getCIntegerField("_current_mileage"), 0);
|
||||||
argReturnedField = new CIntField(type.getCIntegerField("_arg_returned"), 0);
|
argReturnedField = new CIntField(type.getCIntegerField("_arg_returned"), 0);
|
||||||
argStackField = new CIntField(type.getCIntegerField("_arg_stack"), 0);
|
argStackField = new CIntField(type.getCIntegerField("_arg_stack"), 0);
|
||||||
@ -61,7 +62,7 @@ public class ciMethodData extends ciMetadata implements MethodDataInterface<ciKl
|
|||||||
parametersTypeDataDi = new CIntField(typeMethodData.getCIntegerField("_parameters_type_data_di"), 0);
|
parametersTypeDataDi = new CIntField(typeMethodData.getCIntegerField("_parameters_type_data_di"), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AddressField origField;
|
private static Field origField;
|
||||||
private static CIntField currentMileageField;
|
private static CIntField currentMileageField;
|
||||||
private static CIntField argReturnedField;
|
private static CIntField argReturnedField;
|
||||||
private static CIntField argStackField;
|
private static CIntField argStackField;
|
||||||
@ -106,8 +107,8 @@ public class ciMethodData extends ciMetadata implements MethodDataInterface<ciKl
|
|||||||
public byte[] orig() {
|
public byte[] orig() {
|
||||||
// fetch the orig MethodData data between header and dataSize
|
// fetch the orig MethodData data between header and dataSize
|
||||||
Address base = getAddress().addOffsetTo(origField.getOffset());
|
Address base = getAddress().addOffsetTo(origField.getOffset());
|
||||||
byte[] result = new byte[MethodData.sizeofMethodDataOopDesc];
|
byte[] result = new byte[(int)origField.getType().getSize()];
|
||||||
for (int i = 0; i < MethodData.sizeofMethodDataOopDesc; i++) {
|
for (int i = 0; i < result.length; i++) {
|
||||||
result[i] = base.getJByteAt(i);
|
result[i] = base.getJByteAt(i);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -116,7 +117,7 @@ public class ciMethodData extends ciMetadata implements MethodDataInterface<ciKl
|
|||||||
public long[] data() {
|
public long[] data() {
|
||||||
// Read the data as an array of intptr_t elements
|
// Read the data as an array of intptr_t elements
|
||||||
Address base = dataField.getValue(getAddress());
|
Address base = dataField.getValue(getAddress());
|
||||||
int elements = dataSize() / MethodData.cellSize;
|
int elements = (dataSize() + extraDataSize()) / MethodData.cellSize;
|
||||||
long[] result = new long[elements];
|
long[] result = new long[elements];
|
||||||
for (int i = 0; i < elements; i++) {
|
for (int i = 0; i < elements; i++) {
|
||||||
Address value = base.getAddressAt(i * MethodData.cellSize);
|
Address value = base.getAddressAt(i * MethodData.cellSize);
|
||||||
@ -148,8 +149,7 @@ public class ciMethodData extends ciMetadata implements MethodDataInterface<ciKl
|
|||||||
}
|
}
|
||||||
|
|
||||||
ParametersTypeData<ciKlass,ciMethod> parametersTypeData() {
|
ParametersTypeData<ciKlass,ciMethod> parametersTypeData() {
|
||||||
Address base = getAddress().addOffsetTo(origField.getOffset());
|
int di = (int)parametersTypeDataDi.getValue(getMetadata().getAddress());
|
||||||
int di = (int)parametersTypeDataDi.getValue(base);
|
|
||||||
if (di == -1 || di == -2) {
|
if (di == -1 || di == -2) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -81,9 +81,8 @@ public class DataLayout {
|
|||||||
return data.getJShortAt(offset + at) & 0xffff;
|
return data.getJShortAt(offset + at) & 0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellAt(int index) {
|
long cellAt(int index) {
|
||||||
// Cells are intptr_t sized but only contain ints as raw values
|
return data.getCIntegerAt(offset + cellOffset(index), MethodData.cellSize, false);
|
||||||
return (int)data.getCIntegerAt(offset + cellOffset(index), MethodData.cellSize, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Address addressAt(int index) {
|
public Address addressAt(int index) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -51,7 +51,7 @@ public abstract class ProfileData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Low-level accessors for underlying data
|
// Low-level accessors for underlying data
|
||||||
int intptrAt(int index) {
|
long intptrAt(int index) {
|
||||||
//assert(0 <= index && index < cellCount(), "oob");
|
//assert(0 <= index && index < cellCount(), "oob");
|
||||||
return data().cellAt(index);
|
return data().cellAt(index);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -48,17 +48,17 @@ public abstract class TypeEntries<K,M> {
|
|||||||
final MethodDataInterface<K,M> methodData;
|
final MethodDataInterface<K,M> methodData;
|
||||||
|
|
||||||
boolean wasNullSeen(int index) {
|
boolean wasNullSeen(int index) {
|
||||||
int v = pd.intptrAt(index);
|
long v = pd.intptrAt(index);
|
||||||
return (v & nullSeen) != 0;
|
return (v & nullSeen) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isTypeUnknown(int index) {
|
boolean isTypeUnknown(int index) {
|
||||||
int v = pd.intptrAt(index);
|
long v = pd.intptrAt(index);
|
||||||
return (v & typeUnknown) != 0;
|
return (v & typeUnknown) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isTypeNone(int index) {
|
boolean isTypeNone(int index) {
|
||||||
int v = pd.intptrAt(index);
|
long v = pd.intptrAt(index);
|
||||||
return (v & typeMask) == 0;
|
return (v & typeMask) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -43,6 +43,7 @@ import jdk.test.lib.process.ProcessTools;
|
|||||||
import jdk.test.lib.process.OutputAnalyzer;
|
import jdk.test.lib.process.OutputAnalyzer;
|
||||||
import jdk.test.lib.Asserts;
|
import jdk.test.lib.Asserts;
|
||||||
import jdk.test.lib.Utils;
|
import jdk.test.lib.Utils;
|
||||||
|
import jdk.test.lib.util.CoreUtils;
|
||||||
|
|
||||||
public abstract class CiReplayBase {
|
public abstract class CiReplayBase {
|
||||||
public static final String REPLAY_FILE_NAME = "test_replay.txt";
|
public static final String REPLAY_FILE_NAME = "test_replay.txt";
|
||||||
@ -65,17 +66,27 @@ public abstract class CiReplayBase {
|
|||||||
"-XX:MetaspaceSize=4m", "-XX:MaxMetaspaceSize=16m", "-XX:InitialCodeCacheSize=512k",
|
"-XX:MetaspaceSize=4m", "-XX:MaxMetaspaceSize=16m", "-XX:InitialCodeCacheSize=512k",
|
||||||
"-XX:ReservedCodeCacheSize=4m", "-XX:ThreadStackSize=512", "-XX:VMThreadStackSize=512",
|
"-XX:ReservedCodeCacheSize=4m", "-XX:ThreadStackSize=512", "-XX:VMThreadStackSize=512",
|
||||||
"-XX:CompilerThreadStackSize=512", "-XX:ParallelGCThreads=1", "-XX:CICompilerCount=2",
|
"-XX:CompilerThreadStackSize=512", "-XX:ParallelGCThreads=1", "-XX:CICompilerCount=2",
|
||||||
"-Xcomp", "-XX:CICrashAt=1", "-XX:+DumpReplayDataOnError",
|
"-XX:-BackgroundCompilation", "-XX:CompileCommand=inline,java.io.PrintStream::*",
|
||||||
"-XX:+PreferInterpreterNativeStubs", "-XX:+PrintCompilation", REPLAY_FILE_OPTION};
|
"-XX:+IgnoreUnrecognizedVMOptions", "-XX:TypeProfileLevel=222", // extra profile data as a stress test
|
||||||
|
"-XX:CICrashAt=1", "-XX:+DumpReplayDataOnError",
|
||||||
|
"-XX:+PreferInterpreterNativeStubs", REPLAY_FILE_OPTION};
|
||||||
private static final String[] REPLAY_OPTIONS = new String[]{DISABLE_COREDUMP_ON_CRASH,
|
private static final String[] REPLAY_OPTIONS = new String[]{DISABLE_COREDUMP_ON_CRASH,
|
||||||
|
"-XX:+IgnoreUnrecognizedVMOptions", "-XX:TypeProfileLevel=222",
|
||||||
"-XX:+ReplayCompiles", REPLAY_FILE_OPTION};
|
"-XX:+ReplayCompiles", REPLAY_FILE_OPTION};
|
||||||
protected final Optional<Boolean> runServer;
|
protected final Optional<Boolean> runServer;
|
||||||
private static int dummy;
|
private static int dummy;
|
||||||
|
|
||||||
public static class TestMain {
|
public static class TestMain {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// Do something because empty methods might not be called/compiled.
|
for (int i = 0; i < 20_000; i++) {
|
||||||
dummy = 42;
|
test(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test(int i) {
|
||||||
|
if ((i % 1000) == 0) {
|
||||||
|
System.out.println("Hello World!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +114,7 @@ public abstract class CiReplayBase {
|
|||||||
|
|
||||||
public void runTest(boolean needCoreDump, String... args) {
|
public void runTest(boolean needCoreDump, String... args) {
|
||||||
cleanup();
|
cleanup();
|
||||||
if (generateReplay(needCoreDump)) {
|
if (generateReplay(needCoreDump, args)) {
|
||||||
testAction();
|
testAction();
|
||||||
cleanup();
|
cleanup();
|
||||||
} else {
|
} else {
|
||||||
@ -143,11 +154,16 @@ public abstract class CiReplayBase {
|
|||||||
options.addAll(Arrays.asList(REPLAY_GENERATION_OPTIONS));
|
options.addAll(Arrays.asList(REPLAY_GENERATION_OPTIONS));
|
||||||
options.addAll(Arrays.asList(vmopts));
|
options.addAll(Arrays.asList(vmopts));
|
||||||
options.add(needCoreDump ? ENABLE_COREDUMP_ON_CRASH : DISABLE_COREDUMP_ON_CRASH);
|
options.add(needCoreDump ? ENABLE_COREDUMP_ON_CRASH : DISABLE_COREDUMP_ON_CRASH);
|
||||||
options.add(TestMain.class.getName());
|
|
||||||
if (needCoreDump) {
|
if (needCoreDump) {
|
||||||
crashOut = ProcessTools.executeProcess(getTestJvmCommandlineWithPrefix(
|
// CiReplayBase$TestMain needs to be quoted because of shell eval
|
||||||
RUN_SHELL_NO_LIMIT, options.toArray(new String[0])));
|
options.add("-XX:CompileOnly='" + TestMain.class.getName() + "::test'");
|
||||||
|
options.add("'" + TestMain.class.getName() + "'");
|
||||||
|
crashOut = ProcessTools.executeProcess(
|
||||||
|
CoreUtils.addCoreUlimitCommand(
|
||||||
|
ProcessTools.createTestJvm(options.toArray(new String[0]))));
|
||||||
} else {
|
} else {
|
||||||
|
options.add("-XX:CompileOnly=" + TestMain.class.getName() + "::test");
|
||||||
|
options.add(TestMain.class.getName());
|
||||||
crashOut = ProcessTools.executeProcess(ProcessTools.createTestJvm(options));
|
crashOut = ProcessTools.executeProcess(ProcessTools.createTestJvm(options));
|
||||||
}
|
}
|
||||||
crashOutputString = crashOut.getOutput();
|
crashOutputString = crashOut.getOutput();
|
||||||
@ -159,18 +175,8 @@ public abstract class CiReplayBase {
|
|||||||
throw new Error("Can't create replay: " + t, t);
|
throw new Error("Can't create replay: " + t, t);
|
||||||
}
|
}
|
||||||
if (needCoreDump) {
|
if (needCoreDump) {
|
||||||
String coreFileLocation = getCoreFileLocation(crashOutputString);
|
|
||||||
if (coreFileLocation == null) {
|
|
||||||
if (Platform.isOSX()) {
|
|
||||||
File coresDir = new File("/cores");
|
|
||||||
if (!coresDir.isDirectory() || !coresDir.canWrite()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new Error("Couldn't find core file location in: '" + crashOutputString + "'");
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
Asserts.assertGT(new File(coreFileLocation).length(), 0L, "Unexpected core size");
|
String coreFileLocation = CoreUtils.getCoreFileLocation(crashOutputString, crashOut.pid());
|
||||||
Files.move(Paths.get(coreFileLocation), Paths.get(TEST_CORE_FILE_NAME));
|
Files.move(Paths.get(coreFileLocation), Paths.get(TEST_CORE_FILE_NAME));
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
throw new Error("Can't move core file: " + ioe, ioe);
|
throw new Error("Can't move core file: " + ioe, ioe);
|
||||||
@ -250,48 +256,6 @@ public abstract class CiReplayBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// lets search few possible locations using process output and return existing location
|
|
||||||
private String getCoreFileLocation(String crashOutputString) {
|
|
||||||
Asserts.assertTrue(crashOutputString.contains(LOCATIONS_STRING),
|
|
||||||
"Output doesn't contain the location of core file, see crash.out");
|
|
||||||
String stringWithLocation = Arrays.stream(crashOutputString.split("\\r?\\n"))
|
|
||||||
.filter(str -> str.contains(LOCATIONS_STRING))
|
|
||||||
.findFirst()
|
|
||||||
.get();
|
|
||||||
stringWithLocation = stringWithLocation.substring(stringWithLocation
|
|
||||||
.indexOf(LOCATIONS_STRING) + LOCATIONS_STRING.length());
|
|
||||||
String coreWithPid;
|
|
||||||
if (stringWithLocation.contains("or ") && !Platform.isWindows()) {
|
|
||||||
Matcher m = Pattern.compile("or.* ([^ ]+[^\\)])\\)?").matcher(stringWithLocation);
|
|
||||||
if (!m.find()) {
|
|
||||||
throw new Error("Couldn't find path to core inside location string");
|
|
||||||
}
|
|
||||||
coreWithPid = m.group(1);
|
|
||||||
} else {
|
|
||||||
coreWithPid = stringWithLocation.trim();
|
|
||||||
}
|
|
||||||
if (new File(coreWithPid).exists()) {
|
|
||||||
return coreWithPid;
|
|
||||||
}
|
|
||||||
String justCore = Paths.get("core").toString();
|
|
||||||
if (new File(justCore).exists()) {
|
|
||||||
return justCore;
|
|
||||||
}
|
|
||||||
Path coreWithPidPath = Paths.get(coreWithPid);
|
|
||||||
String justFile = coreWithPidPath.getFileName().toString();
|
|
||||||
if (new File(justFile).exists()) {
|
|
||||||
return justFile;
|
|
||||||
}
|
|
||||||
Path parent = coreWithPidPath.getParent();
|
|
||||||
if (parent != null) {
|
|
||||||
String coreWithoutPid = parent.resolve("core").toString();
|
|
||||||
if (new File(coreWithoutPid).exists()) {
|
|
||||||
return coreWithoutPid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String[] getTestJvmCommandlineWithPrefix(String prefix, String... args) {
|
private String[] getTestJvmCommandlineWithPrefix(String prefix, String... args) {
|
||||||
try {
|
try {
|
||||||
String cmd = ProcessTools.getCommandLine(ProcessTools.createTestJvm(args));
|
String cmd = ProcessTools.getCommandLine(ProcessTools.createTestJvm(args));
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2020, 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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,6 +25,8 @@ package compiler.ciReplay;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@ -41,7 +43,19 @@ public class SABase extends CiReplayBase {
|
|||||||
|
|
||||||
public static void main(String args[]) throws Exception {
|
public static void main(String args[]) throws Exception {
|
||||||
checkSetLimits();
|
checkSetLimits();
|
||||||
new SABase(args).runTest(/* needCoreDump = */ true, args);
|
SABase base = new SABase(args);
|
||||||
|
boolean c2 = base.runServer.orElseThrow(() -> new Error("runServer must be set"));
|
||||||
|
String[] extra = {};
|
||||||
|
if (Platform.isTieredSupported()) {
|
||||||
|
if (c2) {
|
||||||
|
// Replay produced on first compilation. We want that
|
||||||
|
// compilation delayed so profile data is produced.
|
||||||
|
extra = new String[] {"-XX:-TieredCompilation"};
|
||||||
|
} else {
|
||||||
|
extra = new String[] {"-XX:TieredStopAtLevel=1"};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base.runTest(/* needCoreDump = */ true, extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SABase(String[] args) {
|
public SABase(String[] args) {
|
||||||
@ -96,19 +110,42 @@ public class SABase extends CiReplayBase {
|
|||||||
File replay = new File(REPLAY_FILE_NAME);
|
File replay = new File(REPLAY_FILE_NAME);
|
||||||
Asserts.assertTrue(replay.exists() && replay.isFile() && replay.length() > 0,
|
Asserts.assertTrue(replay.exists() && replay.isFile() && replay.length() > 0,
|
||||||
"Replay data wasn't generated by SA");
|
"Replay data wasn't generated by SA");
|
||||||
|
// other than comment lines, content of 2 files should be identical
|
||||||
try {
|
try {
|
||||||
FileInputStream rep = new FileInputStream(replay);
|
BufferedReader rep = new BufferedReader(new FileReader(replay));
|
||||||
FileInputStream repCopy = new FileInputStream(REPLAY_FILE_COPY);
|
BufferedReader repCopy = new BufferedReader(new FileReader(REPLAY_FILE_COPY));
|
||||||
byte repBuffer[] = new byte[512];
|
boolean failure = false;
|
||||||
byte repCopyBuffer[] = new byte[512];
|
while (true) {
|
||||||
boolean filesNotEqual = false;
|
String l1;
|
||||||
while(rep.available() > 0 && !filesNotEqual) {
|
while ((l1 = rep.readLine()) != null) {
|
||||||
int count = rep.read(repBuffer);
|
if (!l1.startsWith("#")) {
|
||||||
int count2 = repCopy.read(repCopyBuffer);
|
break;
|
||||||
filesNotEqual = count != count2 || Arrays.equals(repBuffer, repCopyBuffer);
|
|
||||||
}
|
}
|
||||||
if (filesNotEqual) {
|
}
|
||||||
|
String l2;
|
||||||
|
while ((l2 = repCopy.readLine()) != null) {
|
||||||
|
if (!l2.startsWith("#")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (l1 == null || l2 == null) {
|
||||||
|
if (l1 != null || l2 != null) {
|
||||||
System.out.println("Warning: replay files are not equal");
|
System.out.println("Warning: replay files are not equal");
|
||||||
|
System.out.println("1: " + l1);
|
||||||
|
System.out.println("2: " + l2);
|
||||||
|
failure = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!l1.equals(l2)) {
|
||||||
|
System.out.println("Warning: replay files are not equal");
|
||||||
|
System.out.println("1: " + l1);
|
||||||
|
System.out.println("2: " + l2);
|
||||||
|
failure = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (failure) {
|
||||||
|
throw new RuntimeException("Warning: replay files are not equal");
|
||||||
}
|
}
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
throw new Error("Can't read replay files: " + ioe, ioe);
|
throw new Error("Can't read replay files: " + ioe, ioe);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -30,7 +30,7 @@ import sun.hotspot.WhiteBox;
|
|||||||
public class VMBase extends CiReplayBase {
|
public class VMBase extends CiReplayBase {
|
||||||
|
|
||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
new VMBase(args).runTest(/* needCoreDump = */ false, args);
|
new VMBase(args).runTest(/* needCoreDump = */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public VMBase(String[] args) {
|
public VMBase(String[] args) {
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -98,7 +98,7 @@ public class ClhsdbCDSCore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
coreFileName = CoreUtils.getCoreFileLocation(crashOutput.getStdout());
|
coreFileName = CoreUtils.getCoreFileLocation(crashOutput.getStdout(), crashOutput.pid());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
cleanup();
|
cleanup();
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -99,7 +99,7 @@ public class ClhsdbFindPC {
|
|||||||
|
|
||||||
// Get the core file name if we are debugging a core instead of live process
|
// Get the core file name if we are debugging a core instead of live process
|
||||||
if (withCore) {
|
if (withCore) {
|
||||||
coreFileName = CoreUtils.getCoreFileLocation(theApp.getOutput().getStdout());
|
coreFileName = CoreUtils.getCoreFileLocation(theApp.getOutput().getStdout(), theApp.getPid());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run 'jstack -v' command to get the findpc address
|
// Run 'jstack -v' command to get the findpc address
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -65,7 +65,7 @@ public class ClhsdbPmap {
|
|||||||
|
|
||||||
if (withCore) {
|
if (withCore) {
|
||||||
String crashOutput = theApp.getOutput().getStdout();
|
String crashOutput = theApp.getOutput().getStdout();
|
||||||
coreFileName = CoreUtils.getCoreFileLocation(crashOutput);
|
coreFileName = CoreUtils.getCoreFileLocation(crashOutput, theApp.getPid());
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> cmds = List.of("pmap");
|
List<String> cmds = List.of("pmap");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -65,7 +65,7 @@ public class ClhsdbPstack {
|
|||||||
|
|
||||||
if (withCore) {
|
if (withCore) {
|
||||||
String crashOutput = theApp.getOutput().getStdout();
|
String crashOutput = theApp.getOutput().getStdout();
|
||||||
coreFileName = CoreUtils.getCoreFileLocation(crashOutput);
|
coreFileName = CoreUtils.getCoreFileLocation(crashOutput, theApp.getPid());
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> cmds = List.of("pstack -v");
|
List<String> cmds = List.of("pstack -v");
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -79,7 +79,7 @@ public class TestJmapCore {
|
|||||||
pb = CoreUtils.addCoreUlimitCommand(pb);
|
pb = CoreUtils.addCoreUlimitCommand(pb);
|
||||||
OutputAnalyzer output = ProcessTools.executeProcess(pb);
|
OutputAnalyzer output = ProcessTools.executeProcess(pb);
|
||||||
|
|
||||||
String coreFileName = CoreUtils.getCoreFileLocation(output.getStdout());
|
String coreFileName = CoreUtils.getCoreFileLocation(output.getStdout(), output.pid());
|
||||||
File core = new File(coreFileName);
|
File core = new File(coreFileName);
|
||||||
File dumpFile = new File("heap.hprof");
|
File dumpFile = new File("heap.hprof");
|
||||||
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
|
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -566,6 +566,15 @@ public final class OutputAnalyzer {
|
|||||||
return buffer.getExitValue();
|
return buffer.getExitValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the process' pid
|
||||||
|
*
|
||||||
|
* @return pid
|
||||||
|
*/
|
||||||
|
public long pid() {
|
||||||
|
return buffer.pid();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the contents of the output buffer (stdout and stderr) as list of strings.
|
* Get the contents of the output buffer (stdout and stderr) as list of strings.
|
||||||
* Output will be split by newlines.
|
* Output will be split by newlines.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -69,6 +69,13 @@ public interface OutputBuffer {
|
|||||||
public String getStderr();
|
public String getStderr();
|
||||||
public int getExitValue();
|
public int getExitValue();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the pid if available
|
||||||
|
*
|
||||||
|
* @return pid
|
||||||
|
*/
|
||||||
|
public long pid();
|
||||||
|
|
||||||
public static OutputBuffer of(Process p, Charset cs) {
|
public static OutputBuffer of(Process p, Charset cs) {
|
||||||
return new LazyOutputBuffer(p, cs);
|
return new LazyOutputBuffer(p, cs);
|
||||||
}
|
}
|
||||||
@ -157,6 +164,11 @@ public interface OutputBuffer {
|
|||||||
throw new OutputBufferException(e);
|
throw new OutputBufferException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long pid() {
|
||||||
|
return p.pid();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EagerOutputBuffer implements OutputBuffer {
|
class EagerOutputBuffer implements OutputBuffer {
|
||||||
@ -184,5 +196,10 @@ public interface OutputBuffer {
|
|||||||
public int getExitValue() {
|
public int getExitValue() {
|
||||||
return exitValue;
|
return exitValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long pid() {
|
||||||
|
throw new RuntimeException("no process");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -101,7 +101,7 @@ public class CoreUtils {
|
|||||||
* @param crashOutputString {@code String} to search in for the core file path
|
* @param crashOutputString {@code String} to search in for the core file path
|
||||||
* @return Location of core file if found in the output, otherwise {@code null}.
|
* @return Location of core file if found in the output, otherwise {@code null}.
|
||||||
*/
|
*/
|
||||||
public static String getCoreFileLocation(String crashOutputString) throws IOException {
|
public static String getCoreFileLocation(String crashOutputString, long pid) throws IOException {
|
||||||
unzipCores(new File("."));
|
unzipCores(new File("."));
|
||||||
|
|
||||||
// Find the core file
|
// Find the core file
|
||||||
@ -124,7 +124,8 @@ public class CoreUtils {
|
|||||||
return coreFileLocation; // success!
|
return coreFileLocation; // success!
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if we can figure out the likely reason the core file was not found.
|
// See if we can figure out the likely reason the core file was not found. Recover from
|
||||||
|
// failure if possible.
|
||||||
// Throw SkippedException if appropriate.
|
// Throw SkippedException if appropriate.
|
||||||
if (Platform.isOSX()) {
|
if (Platform.isOSX()) {
|
||||||
File coresDir = new File("/cores");
|
File coresDir = new File("/cores");
|
||||||
@ -152,6 +153,30 @@ public class CoreUtils {
|
|||||||
line = line.trim();
|
line = line.trim();
|
||||||
System.out.println(line);
|
System.out.println(line);
|
||||||
if (line.startsWith("|")) {
|
if (line.startsWith("|")) {
|
||||||
|
if (line.split("\s", 2)[0].endsWith("systemd-coredump")) {
|
||||||
|
// A systemd linux system. Try to retrieve core
|
||||||
|
// file. It can take a few seconds for the system to
|
||||||
|
// process the just produced core file so we may need to
|
||||||
|
// retry a few times.
|
||||||
|
System.out.println("Running systemd-coredump: trying coredumpctl command");
|
||||||
|
String core = "core";
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
Thread.sleep(5000);
|
||||||
|
OutputAnalyzer out = ProcessTools.executeProcess("coredumpctl", "dump", "-1", "-o", core, String.valueOf(pid));
|
||||||
|
if (!out.getOutput().contains("output may be incomplete")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(Throwable t) {
|
||||||
|
}
|
||||||
|
final File coreFile = new File(core);
|
||||||
|
if (coreFile.exists()) {
|
||||||
|
Asserts.assertGT(coreFile.length(), 0L, "Unexpected core size");
|
||||||
|
System.out.println("coredumpctl succeeded");
|
||||||
|
return core;
|
||||||
|
}
|
||||||
|
}
|
||||||
System.out.println(
|
System.out.println(
|
||||||
"\nThis system uses a crash report tool ($cat /proc/sys/kernel/core_pattern).\n" +
|
"\nThis system uses a crash report tool ($cat /proc/sys/kernel/core_pattern).\n" +
|
||||||
"Core files might not be generated. Please reset /proc/sys/kernel/core_pattern\n" +
|
"Core files might not be generated. Please reset /proc/sys/kernel/core_pattern\n" +
|
||||||
|
Loading…
Reference in New Issue
Block a user