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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,6 +27,9 @@
|
||||
#include "ci/ciUtilities.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
|
||||
//
|
||||
|
@ -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.
|
||||
*
|
||||
* 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* o): _metadata(o) {}
|
||||
|
||||
virtual bool is_classless() const { return false; }
|
||||
virtual bool is_classless() const;
|
||||
public:
|
||||
bool is_loaded() const { return _metadata != NULL || is_classless(); }
|
||||
|
||||
|
@ -1256,7 +1256,7 @@ void MethodData::initialize() {
|
||||
object_size += extra_size + arg_data_size;
|
||||
|
||||
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
|
||||
// for method entry so they don't fit with the framework for the
|
||||
// profiling of bytecodes). We store the offset within the MDO of
|
||||
|
@ -261,7 +261,7 @@ typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
|
||||
nonstatic_field(Klass, _java_mirror, OopHandle) \
|
||||
nonstatic_field(Klass, _modifier_flags, jint) \
|
||||
nonstatic_field(Klass, _super, Klass*) \
|
||||
volatile_nonstatic_field(Klass, _subklass, Klass*) \
|
||||
volatile_nonstatic_field(Klass, _subklass, Klass*) \
|
||||
nonstatic_field(Klass, _layout_helper, jint) \
|
||||
nonstatic_field(Klass, _name, Symbol*) \
|
||||
nonstatic_field(Klass, _access_flags, AccessFlags) \
|
||||
|
@ -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.
|
||||
*
|
||||
* 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.oops.*;
|
||||
import sun.jvm.hotspot.types.*;
|
||||
import sun.jvm.hotspot.types.Field;
|
||||
import sun.jvm.hotspot.utilities.Observable;
|
||||
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 {
|
||||
Type type = db.lookupType("ciMethodData");
|
||||
origField = type.getAddressField("_orig");
|
||||
origField = type.getField("_orig");
|
||||
currentMileageField = new CIntField(type.getCIntegerField("_current_mileage"), 0);
|
||||
argReturnedField = new CIntField(type.getCIntegerField("_arg_returned"), 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);
|
||||
}
|
||||
|
||||
private static AddressField origField;
|
||||
private static Field origField;
|
||||
private static CIntField currentMileageField;
|
||||
private static CIntField argReturnedField;
|
||||
private static CIntField argStackField;
|
||||
@ -106,8 +107,8 @@ public class ciMethodData extends ciMetadata implements MethodDataInterface<ciKl
|
||||
public byte[] orig() {
|
||||
// fetch the orig MethodData data between header and dataSize
|
||||
Address base = getAddress().addOffsetTo(origField.getOffset());
|
||||
byte[] result = new byte[MethodData.sizeofMethodDataOopDesc];
|
||||
for (int i = 0; i < MethodData.sizeofMethodDataOopDesc; i++) {
|
||||
byte[] result = new byte[(int)origField.getType().getSize()];
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i] = base.getJByteAt(i);
|
||||
}
|
||||
return result;
|
||||
@ -116,7 +117,7 @@ public class ciMethodData extends ciMetadata implements MethodDataInterface<ciKl
|
||||
public long[] data() {
|
||||
// Read the data as an array of intptr_t elements
|
||||
Address base = dataField.getValue(getAddress());
|
||||
int elements = dataSize() / MethodData.cellSize;
|
||||
int elements = (dataSize() + extraDataSize()) / MethodData.cellSize;
|
||||
long[] result = new long[elements];
|
||||
for (int i = 0; i < elements; i++) {
|
||||
Address value = base.getAddressAt(i * MethodData.cellSize);
|
||||
@ -148,8 +149,7 @@ public class ciMethodData extends ciMetadata implements MethodDataInterface<ciKl
|
||||
}
|
||||
|
||||
ParametersTypeData<ciKlass,ciMethod> parametersTypeData() {
|
||||
Address base = getAddress().addOffsetTo(origField.getOffset());
|
||||
int di = (int)parametersTypeDataDi.getValue(base);
|
||||
int di = (int)parametersTypeDataDi.getValue(getMetadata().getAddress());
|
||||
if (di == -1 || di == -2) {
|
||||
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.
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
|
||||
int cellAt(int index) {
|
||||
// Cells are intptr_t sized but only contain ints as raw values
|
||||
return (int)data.getCIntegerAt(offset + cellOffset(index), MethodData.cellSize, false);
|
||||
long cellAt(int index) {
|
||||
return data.getCIntegerAt(offset + cellOffset(index), MethodData.cellSize, false);
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -234,8 +234,8 @@ public class MethodData extends Metadata implements MethodDataInterface<Klass,Me
|
||||
public void iterateFields(MetadataVisitor visitor) {
|
||||
super.iterateFields(visitor);
|
||||
visitor.doMetadata(method, true);
|
||||
visitor.doCInt(size, true);
|
||||
}
|
||||
visitor.doCInt(size, true);
|
||||
}
|
||||
|
||||
int dataSize() {
|
||||
if (dataSize == null) {
|
||||
|
@ -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.
|
||||
*
|
||||
* 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
|
||||
int intptrAt(int index) {
|
||||
long intptrAt(int index) {
|
||||
//assert(0 <= index && index < cellCount(), "oob");
|
||||
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.
|
||||
*
|
||||
* 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;
|
||||
|
||||
boolean wasNullSeen(int index) {
|
||||
int v = pd.intptrAt(index);
|
||||
long v = pd.intptrAt(index);
|
||||
return (v & nullSeen) != 0;
|
||||
}
|
||||
|
||||
boolean isTypeUnknown(int index) {
|
||||
int v = pd.intptrAt(index);
|
||||
long v = pd.intptrAt(index);
|
||||
return (v & typeUnknown) != 0;
|
||||
}
|
||||
|
||||
boolean isTypeNone(int index) {
|
||||
int v = pd.intptrAt(index);
|
||||
long v = pd.intptrAt(index);
|
||||
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.
|
||||
*
|
||||
* 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.Asserts;
|
||||
import jdk.test.lib.Utils;
|
||||
import jdk.test.lib.util.CoreUtils;
|
||||
|
||||
public abstract class CiReplayBase {
|
||||
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:ReservedCodeCacheSize=4m", "-XX:ThreadStackSize=512", "-XX:VMThreadStackSize=512",
|
||||
"-XX:CompilerThreadStackSize=512", "-XX:ParallelGCThreads=1", "-XX:CICompilerCount=2",
|
||||
"-Xcomp", "-XX:CICrashAt=1", "-XX:+DumpReplayDataOnError",
|
||||
"-XX:+PreferInterpreterNativeStubs", "-XX:+PrintCompilation", REPLAY_FILE_OPTION};
|
||||
"-XX:-BackgroundCompilation", "-XX:CompileCommand=inline,java.io.PrintStream::*",
|
||||
"-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,
|
||||
"-XX:+IgnoreUnrecognizedVMOptions", "-XX:TypeProfileLevel=222",
|
||||
"-XX:+ReplayCompiles", REPLAY_FILE_OPTION};
|
||||
protected final Optional<Boolean> runServer;
|
||||
private static int dummy;
|
||||
|
||||
public static class TestMain {
|
||||
public static void main(String[] args) {
|
||||
// Do something because empty methods might not be called/compiled.
|
||||
dummy = 42;
|
||||
for (int i = 0; i < 20_000; i++) {
|
||||
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) {
|
||||
cleanup();
|
||||
if (generateReplay(needCoreDump)) {
|
||||
if (generateReplay(needCoreDump, args)) {
|
||||
testAction();
|
||||
cleanup();
|
||||
} else {
|
||||
@ -143,11 +154,16 @@ public abstract class CiReplayBase {
|
||||
options.addAll(Arrays.asList(REPLAY_GENERATION_OPTIONS));
|
||||
options.addAll(Arrays.asList(vmopts));
|
||||
options.add(needCoreDump ? ENABLE_COREDUMP_ON_CRASH : DISABLE_COREDUMP_ON_CRASH);
|
||||
options.add(TestMain.class.getName());
|
||||
if (needCoreDump) {
|
||||
crashOut = ProcessTools.executeProcess(getTestJvmCommandlineWithPrefix(
|
||||
RUN_SHELL_NO_LIMIT, options.toArray(new String[0])));
|
||||
// CiReplayBase$TestMain needs to be quoted because of shell eval
|
||||
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 {
|
||||
options.add("-XX:CompileOnly=" + TestMain.class.getName() + "::test");
|
||||
options.add(TestMain.class.getName());
|
||||
crashOut = ProcessTools.executeProcess(ProcessTools.createTestJvm(options));
|
||||
}
|
||||
crashOutputString = crashOut.getOutput();
|
||||
@ -159,18 +175,8 @@ public abstract class CiReplayBase {
|
||||
throw new Error("Can't create replay: " + t, t);
|
||||
}
|
||||
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 {
|
||||
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));
|
||||
} catch (IOException 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) {
|
||||
try {
|
||||
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.
|
||||
*
|
||||
* 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.Paths;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
@ -41,7 +43,19 @@ public class SABase extends CiReplayBase {
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
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) {
|
||||
@ -96,19 +110,42 @@ public class SABase extends CiReplayBase {
|
||||
File replay = new File(REPLAY_FILE_NAME);
|
||||
Asserts.assertTrue(replay.exists() && replay.isFile() && replay.length() > 0,
|
||||
"Replay data wasn't generated by SA");
|
||||
// other than comment lines, content of 2 files should be identical
|
||||
try {
|
||||
FileInputStream rep = new FileInputStream(replay);
|
||||
FileInputStream repCopy = new FileInputStream(REPLAY_FILE_COPY);
|
||||
byte repBuffer[] = new byte[512];
|
||||
byte repCopyBuffer[] = new byte[512];
|
||||
boolean filesNotEqual = false;
|
||||
while(rep.available() > 0 && !filesNotEqual) {
|
||||
int count = rep.read(repBuffer);
|
||||
int count2 = repCopy.read(repCopyBuffer);
|
||||
filesNotEqual = count != count2 || Arrays.equals(repBuffer, repCopyBuffer);
|
||||
BufferedReader rep = new BufferedReader(new FileReader(replay));
|
||||
BufferedReader repCopy = new BufferedReader(new FileReader(REPLAY_FILE_COPY));
|
||||
boolean failure = false;
|
||||
while (true) {
|
||||
String l1;
|
||||
while ((l1 = rep.readLine()) != null) {
|
||||
if (!l1.startsWith("#")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
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("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 (filesNotEqual) {
|
||||
System.out.println("Warning: replay files are not equal");
|
||||
if (failure) {
|
||||
throw new RuntimeException("Warning: replay files are not equal");
|
||||
}
|
||||
} catch (IOException 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.
|
||||
*
|
||||
* 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 static void main(String args[]) {
|
||||
new VMBase(args).runTest(/* needCoreDump = */ false, args);
|
||||
new VMBase(args).runTest(/* needCoreDump = */ false);
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -98,7 +98,7 @@ public class ClhsdbCDSCore {
|
||||
}
|
||||
|
||||
try {
|
||||
coreFileName = CoreUtils.getCoreFileLocation(crashOutput.getStdout());
|
||||
coreFileName = CoreUtils.getCoreFileLocation(crashOutput.getStdout(), crashOutput.pid());
|
||||
} catch (Exception e) {
|
||||
cleanup();
|
||||
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.
|
||||
*
|
||||
* 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
|
||||
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
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -65,7 +65,7 @@ public class ClhsdbPmap {
|
||||
|
||||
if (withCore) {
|
||||
String crashOutput = theApp.getOutput().getStdout();
|
||||
coreFileName = CoreUtils.getCoreFileLocation(crashOutput);
|
||||
coreFileName = CoreUtils.getCoreFileLocation(crashOutput, theApp.getPid());
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -65,7 +65,7 @@ public class ClhsdbPstack {
|
||||
|
||||
if (withCore) {
|
||||
String crashOutput = theApp.getOutput().getStdout();
|
||||
coreFileName = CoreUtils.getCoreFileLocation(crashOutput);
|
||||
coreFileName = CoreUtils.getCoreFileLocation(crashOutput, theApp.getPid());
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -77,9 +77,9 @@ public class TestJmapCore {
|
||||
|
||||
// If we are going to force a core dump, apply "ulimit -c unlimited" if we can.
|
||||
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 dumpFile = new File("heap.hprof");
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -566,6 +566,15 @@ public final class OutputAnalyzer {
|
||||
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.
|
||||
* 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -69,6 +69,13 @@ public interface OutputBuffer {
|
||||
public String getStderr();
|
||||
public int getExitValue();
|
||||
|
||||
/**
|
||||
* Returns the pid if available
|
||||
*
|
||||
* @return pid
|
||||
*/
|
||||
public long pid();
|
||||
|
||||
public static OutputBuffer of(Process p, Charset cs) {
|
||||
return new LazyOutputBuffer(p, cs);
|
||||
}
|
||||
@ -157,6 +164,11 @@ public interface OutputBuffer {
|
||||
throw new OutputBufferException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long pid() {
|
||||
return p.pid();
|
||||
}
|
||||
}
|
||||
|
||||
class EagerOutputBuffer implements OutputBuffer {
|
||||
@ -184,5 +196,10 @@ public interface OutputBuffer {
|
||||
public int getExitValue() {
|
||||
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.
|
||||
*
|
||||
* 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
|
||||
* @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("."));
|
||||
|
||||
// Find the core file
|
||||
@ -124,7 +124,8 @@ public class CoreUtils {
|
||||
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.
|
||||
if (Platform.isOSX()) {
|
||||
File coresDir = new File("/cores");
|
||||
@ -152,6 +153,30 @@ public class CoreUtils {
|
||||
line = line.trim();
|
||||
System.out.println(line);
|
||||
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(
|
||||
"\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" +
|
||||
|
Loading…
Reference in New Issue
Block a user