undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
|
|
@ -0,0 +1,761 @@
|
|||
/*
|
||||
* Copyright (c) 2004, 2018, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4982289 8198253
|
||||
* @summary Test ThreadInfo.from to return a valid
|
||||
* ThreadInfo object. Or throw exception if
|
||||
* the input CompositeData is invalid.
|
||||
* @author Mandy Chung
|
||||
*
|
||||
* @modules java.management/sun.management
|
||||
* @build ThreadInfoCompositeData OpenTypeConverter
|
||||
* @run testng/othervm ThreadInfoCompositeData
|
||||
*/
|
||||
|
||||
|
||||
import javax.management.openmbean.*;
|
||||
import java.lang.management.LockInfo;
|
||||
import java.lang.management.MonitorInfo;
|
||||
import java.lang.management.ThreadInfo;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
public class ThreadInfoCompositeData {
|
||||
private static String lockClassName = "myClass";
|
||||
private static int lockIdentityHashCode = 123456;
|
||||
private static String lockName = lockClassName + '@' +
|
||||
Integer.toHexString(lockIdentityHashCode);
|
||||
private static LockInfo lockInfo =
|
||||
new LockInfo(lockClassName, lockIdentityHashCode);
|
||||
|
||||
@Test
|
||||
public static void createGoodCompositeData() throws Exception {
|
||||
CompositeData cd = Factory.makeThreadInfoCompositeData();
|
||||
ThreadInfo info = ThreadInfo.from(cd);
|
||||
checkThreadInfo(info);
|
||||
}
|
||||
|
||||
/*
|
||||
* An invalid CompositeData with JDK 9 attributes but missing JDK 6 attributes
|
||||
*/
|
||||
@Test
|
||||
public static void badMissingCompositeData() throws Exception {
|
||||
CompositeData cd = Factory.makeCompositeDataMissingV6();
|
||||
try {
|
||||
ThreadInfo info = ThreadInfo.from(cd);
|
||||
throw new RuntimeException("IllegalArgumentException not thrown");
|
||||
} catch (IllegalArgumentException e) {}
|
||||
}
|
||||
|
||||
static final StackTraceElement STE =
|
||||
new StackTraceElement("FooClass", "getFoo", "Foo.java", 100);
|
||||
|
||||
|
||||
/*
|
||||
* Current version of ThreadInfo but an older version of StackTraceElement
|
||||
*/
|
||||
@Test
|
||||
public static void withV5StackTraceCompositeData() throws Exception {
|
||||
CompositeData cd = Factory.makeThreadInfoWithV5StackTrace();
|
||||
try {
|
||||
ThreadInfo info = ThreadInfo.from(cd);
|
||||
throw new RuntimeException("IllegalArgumentException not thrown");
|
||||
} catch (IllegalArgumentException e) {}
|
||||
}
|
||||
|
||||
/*
|
||||
* Current version of ThreadInfo but an older version of MonitorInfo
|
||||
* and the value of "lockedStackFrame" attribute is null.
|
||||
*/
|
||||
@Test
|
||||
public static void withInvalidMonitorInfoCompositeData() throws Exception {
|
||||
CompositeData cd = Factory.makeThreadInfoWithIncompatibleMonitorInfo();
|
||||
|
||||
// verify MonitorInfo is valid
|
||||
CompositeData[] monitors = (CompositeData[])cd.get("lockedMonitors");
|
||||
CompositeData ste = (CompositeData)monitors[0].get("lockedStackFrame");
|
||||
if (((Integer)monitors[0].get("lockedStackDepth")) >= 0 || ste != null) {
|
||||
throw new RuntimeException("Expected negative stack depth and null stack frame");
|
||||
}
|
||||
MonitorInfo minfo = MonitorInfo.from(monitors[0]);
|
||||
checkLockInfo(minfo);
|
||||
if (minfo.getLockedStackFrame() != null) {
|
||||
throw new RuntimeException("Expected null stack frame");
|
||||
}
|
||||
|
||||
try {
|
||||
ThreadInfo info = ThreadInfo.from(cd);
|
||||
throw new RuntimeException("IllegalArgumentException not thrown");
|
||||
} catch (IllegalArgumentException e) {}
|
||||
}
|
||||
|
||||
/*
|
||||
* ThreadInfo of version N can accept lockedMonitors of version >= N
|
||||
*/
|
||||
@Test
|
||||
public static void withNewMonitorInfoCompositeData() throws Exception {
|
||||
CompositeData cd = Factory.makeThreadInfoWithNewMonitorInfo();
|
||||
ThreadInfo info = ThreadInfo.from(cd);
|
||||
checkThreadInfo(info);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test CompositeData representing JDK 5 ThreadInfo
|
||||
*/
|
||||
@Test
|
||||
public static void createV5ThreadInfo() throws Exception {
|
||||
CompositeData cd = Factory.makeThreadInfoV5CompositeData();
|
||||
ThreadInfo info = ThreadInfo.from(cd);
|
||||
checkThreadInfoV5(info);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test ThreadInfoCompositeData.toCompositeData
|
||||
*/
|
||||
@Test
|
||||
public static void internalToCompositeData() throws Exception {
|
||||
CompositeData cd = Factory.makeThreadInfoCompositeData();
|
||||
ThreadInfo info = ThreadInfo.from(cd);
|
||||
cd = sun.management.ThreadInfoCompositeData.toCompositeData(info);
|
||||
info = ThreadInfo.from(cd);
|
||||
checkThreadInfo(info);
|
||||
}
|
||||
|
||||
static void checkThreadInfoV5(ThreadInfo info) {
|
||||
Object[] values = Factory.VALUES;
|
||||
|
||||
if (info.getThreadId() != ((Long) values[THREAD_ID]).longValue()) {
|
||||
throw new RuntimeException("Thread Id = " + info.getThreadId() +
|
||||
" expected = " + values[THREAD_ID]);
|
||||
}
|
||||
if (!info.getThreadName().equals(values[THREAD_NAME])) {
|
||||
throw new RuntimeException("Thread Name = " +
|
||||
info.getThreadName() + " expected = " + values[THREAD_NAME]);
|
||||
}
|
||||
if (info.getThreadState() != Thread.State.RUNNABLE) {
|
||||
throw new RuntimeException("Thread Name = " +
|
||||
info.getThreadName() + " expected = " + Thread.State.RUNNABLE);
|
||||
}
|
||||
if (info.getBlockedTime() != ((Long) values[BLOCKED_TIME]).longValue()) {
|
||||
throw new RuntimeException("blocked time = " +
|
||||
info.getBlockedTime() +
|
||||
" expected = " + values[BLOCKED_TIME]);
|
||||
}
|
||||
if (info.getBlockedCount() != ((Long) values[BLOCKED_COUNT]).longValue()) {
|
||||
throw new RuntimeException("blocked count = " +
|
||||
info.getBlockedCount() +
|
||||
" expected = " + values[BLOCKED_COUNT]);
|
||||
}
|
||||
if (info.getWaitedTime() != ((Long) values[WAITED_TIME]).longValue()) {
|
||||
throw new RuntimeException("waited time = " +
|
||||
info.getWaitedTime() +
|
||||
" expected = " + values[WAITED_TIME]);
|
||||
}
|
||||
if (info.getWaitedCount() != ((Long) values[WAITED_COUNT]).longValue()) {
|
||||
throw new RuntimeException("waited count = " +
|
||||
info.getWaitedCount() +
|
||||
" expected = " + values[WAITED_COUNT]);
|
||||
}
|
||||
if (!info.getLockName().equals(values[LOCK_NAME])) {
|
||||
throw new RuntimeException("Lock Name = " +
|
||||
info.getLockName() + " expected = " + values[LOCK_NAME]);
|
||||
}
|
||||
if (info.getLockOwnerId() !=
|
||||
((Long) values[LOCK_OWNER_ID]).longValue()) {
|
||||
throw new RuntimeException(
|
||||
"LockOwner Id = " + info.getLockOwnerId() +
|
||||
" expected = " + values[LOCK_OWNER_ID]);
|
||||
}
|
||||
if (!info.getLockOwnerName().equals(values[LOCK_OWNER_NAME])) {
|
||||
throw new RuntimeException("LockOwner Name = " +
|
||||
info.getLockOwnerName() + " expected = " +
|
||||
values[LOCK_OWNER_NAME]);
|
||||
}
|
||||
|
||||
checkStackTrace(info.getStackTrace());
|
||||
checkLockInfo(info.getLockInfo());
|
||||
}
|
||||
|
||||
static void checkThreadInfo(ThreadInfo info) {
|
||||
Object[] values = Factory.VALUES;
|
||||
|
||||
checkThreadInfoV5(info);
|
||||
|
||||
if (!values[DAEMON].equals(info.isDaemon())) {
|
||||
throw new RuntimeException("Daemon = " +
|
||||
info.isDaemon() + " expected = " + values[DAEMON]);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkStackTrace(StackTraceElement[] s) {
|
||||
if (s.length != 1) {
|
||||
throw new RuntimeException("Stack Trace length = " +
|
||||
s.length + " expected = 1");
|
||||
}
|
||||
|
||||
StackTraceElement s1 = STE;
|
||||
StackTraceElement s2 = s[0];
|
||||
|
||||
// these attributes may be null
|
||||
if (!Objects.equals(s1.getClassLoaderName(), s2.getClassLoaderName())) {
|
||||
throw new RuntimeException("Class loader name = " +
|
||||
s2.getClassLoaderName() + " expected = " + s1.getClassLoaderName());
|
||||
}
|
||||
if (!Objects.equals(s1.getModuleName(), s2.getModuleName())) {
|
||||
throw new RuntimeException("Module name = " +
|
||||
s2.getModuleName() + " expected = " + s1.getModuleName());
|
||||
}
|
||||
if (!Objects.equals(s1.getModuleVersion(), s2.getModuleVersion())) {
|
||||
throw new RuntimeException("Module version = " +
|
||||
s2.getModuleVersion() + " expected = " + s1.getModuleVersion());
|
||||
}
|
||||
|
||||
if (!s1.getClassName().equals(s2.getClassName())) {
|
||||
throw new RuntimeException("Class name = " +
|
||||
s2.getClassName() + " expected = " + s1.getClassName());
|
||||
}
|
||||
if (!s1.getMethodName().equals(s2.getMethodName())) {
|
||||
throw new RuntimeException("Method name = " +
|
||||
s2.getMethodName() + " expected = " + s1.getMethodName());
|
||||
}
|
||||
if (!s1.getFileName().equals(s2.getFileName())) {
|
||||
throw new RuntimeException("File name = " +
|
||||
s2.getFileName() + " expected = " + s1.getFileName());
|
||||
}
|
||||
if (s1.getLineNumber() != s2.getLineNumber()) {
|
||||
throw new RuntimeException("Line number = " +
|
||||
s2.getLineNumber() + " expected = " + s1.getLineNumber());
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkLockInfo(LockInfo li) {
|
||||
if (!li.getClassName().equals(lockInfo.getClassName())) {
|
||||
throw new RuntimeException("Class Name = " +
|
||||
li.getClassName() + " expected = " + lockInfo.getClassName());
|
||||
}
|
||||
if (li.getIdentityHashCode() != lockInfo.getIdentityHashCode()) {
|
||||
throw new RuntimeException("Class Name = " +
|
||||
li.getIdentityHashCode() + " expected = " +
|
||||
lockInfo.getIdentityHashCode());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public static void badNameCompositeData() throws Exception {
|
||||
CompositeData cd = Factory.makeCompositeDataWithBadNames();
|
||||
try {
|
||||
ThreadInfo info = ThreadInfo.from(cd);
|
||||
throw new RuntimeException("IllegalArgumentException not thrown");
|
||||
} catch (IllegalArgumentException e) { }
|
||||
}
|
||||
|
||||
@Test
|
||||
public static void badTypeCompositeData() throws Exception {
|
||||
CompositeData cd = Factory.makeCompositeDataWithBadTypes();
|
||||
|
||||
try {
|
||||
ThreadInfo info = ThreadInfo.from(cd);
|
||||
throw new RuntimeException("IllegalArgumentException not thrown");
|
||||
} catch (IllegalArgumentException e) { }
|
||||
}
|
||||
|
||||
private static final int THREAD_ID = 0;
|
||||
private static final int THREAD_NAME = 1;
|
||||
private static final int THREAD_STATE = 2;
|
||||
private static final int BLOCKED_TIME = 3;
|
||||
private static final int BLOCKED_COUNT = 4;
|
||||
private static final int WAITED_TIME = 5;
|
||||
private static final int WAITED_COUNT = 6;
|
||||
private static final int LOCK_NAME = 7;
|
||||
private static final int LOCK_OWNER_ID = 8;
|
||||
private static final int LOCK_OWNER_NAME = 9;
|
||||
private static final int STACK_TRACE = 10;
|
||||
private static final int SUSPENDED = 11;
|
||||
private static final int IN_NATIVE = 12;
|
||||
// JDK 6 ThreadInfo attributes
|
||||
private static final int LOCK_INFO = 13;
|
||||
private static final int LOCKED_MONITORS = 14;
|
||||
private static final int LOCKED_SYNCS = 15;
|
||||
// JDK 9 ThreadInfo attributes
|
||||
private static final int DAEMON = 16;
|
||||
private static final int PRIORITY = 17;
|
||||
|
||||
private static class Factory {
|
||||
|
||||
static final CompositeType STE_COMPOSITE_TYPE;
|
||||
static final CompositeType LOCK_INFO_COMPOSITE_TYPE;
|
||||
static final CompositeType MONITOR_INFO_COMPOSITE_TYPE;
|
||||
static final ArrayType STE_ARRAY_COMPOSITE_TYPE;
|
||||
static final ArrayType LOCK_INFO_ARRAY_COMPOSITE_TYPE;
|
||||
static final ArrayType MONITOR_INFO_ARRAY_COMPOSITE_TYPE;
|
||||
|
||||
static {
|
||||
CompositeType steCType = null;
|
||||
CompositeType lockInfoCType = null;
|
||||
CompositeType monitorInfoCType = null;
|
||||
ArrayType steArrayType = null;
|
||||
ArrayType lockInfoArrayType = null;
|
||||
ArrayType monitorInfoArrayType = null;
|
||||
|
||||
try {
|
||||
steCType = (CompositeType) OpenTypeConverter.toOpenType(StackTraceElement.class);
|
||||
lockInfoCType = (CompositeType) OpenTypeConverter.toOpenType(LockInfo.class);
|
||||
monitorInfoCType = (CompositeType) OpenTypeConverter.toOpenType(MonitorInfo.class);
|
||||
steArrayType = new ArrayType(1, steCType);
|
||||
lockInfoArrayType = new ArrayType(1, lockInfoCType);
|
||||
monitorInfoArrayType = new ArrayType(1, monitorInfoCType);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
STE_COMPOSITE_TYPE = steCType;
|
||||
LOCK_INFO_COMPOSITE_TYPE = lockInfoCType;
|
||||
MONITOR_INFO_COMPOSITE_TYPE = monitorInfoCType;
|
||||
STE_ARRAY_COMPOSITE_TYPE = steArrayType;
|
||||
LOCK_INFO_ARRAY_COMPOSITE_TYPE = lockInfoArrayType;
|
||||
MONITOR_INFO_ARRAY_COMPOSITE_TYPE = monitorInfoArrayType;
|
||||
}
|
||||
|
||||
static CompositeData makeThreadInfoCompositeData() throws OpenDataException {
|
||||
CompositeType ct = new CompositeType("MyCompositeType",
|
||||
"CompositeType for ThreadInfo",
|
||||
ITEM_NAMES,
|
||||
ITEM_NAMES,
|
||||
ITEM_TYPES);
|
||||
return new CompositeDataSupport(ct, ITEM_NAMES, VALUES);
|
||||
}
|
||||
|
||||
static CompositeData makeThreadInfoV5CompositeData() throws OpenDataException {
|
||||
CompositeType ct = new CompositeType("MyCompositeType",
|
||||
"CompositeType for JDK 5 ThreadInfo",
|
||||
V5_ITEM_NAMES,
|
||||
V5_ITEM_NAMES,
|
||||
V5_ITEM_TYPES);
|
||||
return new CompositeDataSupport(ct, V5_ITEM_NAMES, V5_VALUES);
|
||||
}
|
||||
|
||||
static CompositeData makeCompositeDataWithBadTypes() throws OpenDataException {
|
||||
OpenType[] badItemTypes = {
|
||||
SimpleType.LONG,
|
||||
SimpleType.STRING,
|
||||
SimpleType.STRING,
|
||||
SimpleType.LONG,
|
||||
SimpleType.LONG,
|
||||
SimpleType.LONG,
|
||||
SimpleType.LONG,
|
||||
SimpleType.STRING,
|
||||
SimpleType.LONG,
|
||||
SimpleType.STRING,
|
||||
SimpleType.LONG, // bad type
|
||||
SimpleType.BOOLEAN,
|
||||
SimpleType.BOOLEAN,
|
||||
SimpleType.LONG, // bad type
|
||||
SimpleType.LONG, // bad type
|
||||
SimpleType.LONG, // bad type
|
||||
SimpleType.BOOLEAN,
|
||||
SimpleType.INTEGER,
|
||||
};
|
||||
|
||||
CompositeType ct =
|
||||
new CompositeType("Bad item types",
|
||||
"CompositeType for ThreadInfo",
|
||||
ITEM_NAMES,
|
||||
ITEM_NAMES,
|
||||
badItemTypes);
|
||||
|
||||
// Copy before mutating to avoid affecting other tests.
|
||||
Object[] localValues = VALUES.clone();
|
||||
|
||||
// patch values[STACK_TRACE] to Long
|
||||
localValues[STACK_TRACE] = Long.valueOf(1000);
|
||||
localValues[LOCK_INFO] = Long.valueOf(1000);
|
||||
localValues[LOCKED_MONITORS] = Long.valueOf(1000);
|
||||
localValues[LOCKED_SYNCS] = Long.valueOf(1000);
|
||||
return new CompositeDataSupport(ct, ITEM_NAMES, localValues);
|
||||
}
|
||||
|
||||
static CompositeData makeCompositeDataWithBadNames() throws OpenDataException {
|
||||
String[] badItemNames = ITEM_NAMES.clone();
|
||||
badItemNames[STACK_TRACE] = "BadStackTrace"; // bad item name
|
||||
|
||||
CompositeType ct = new CompositeType("Bad item names",
|
||||
"CompositeType for ThreadInfo",
|
||||
badItemNames,
|
||||
badItemNames,
|
||||
ITEM_TYPES);
|
||||
return new CompositeDataSupport(ct,
|
||||
badItemNames,
|
||||
VALUES);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a CompositeData of ThreadInfo without JDK 6 attributes
|
||||
*/
|
||||
static CompositeData makeCompositeDataMissingV6() throws OpenDataException {
|
||||
String[] itemNames = concat(V5_ITEM_NAMES, V9_ITEM_NAMES).toArray(String[]::new);
|
||||
OpenType[] itemTypes = concat(V5_ITEM_TYPES, V9_ITEM_TYPES).toArray(OpenType[]::new);
|
||||
Object[] values = concat(V5_VALUES, V9_VALUES).toArray(Object[]::new);
|
||||
|
||||
CompositeType ct =
|
||||
new CompositeType("InvalidCompositeType",
|
||||
"CompositeType for ThreadInfo",
|
||||
itemNames,
|
||||
itemNames,
|
||||
itemTypes);
|
||||
return new CompositeDataSupport(ct, itemNames, values);
|
||||
}
|
||||
|
||||
static CompositeData makeStackTraceElement() {
|
||||
Object[] steValue = {
|
||||
STE.getClassLoaderName(),
|
||||
STE.getModuleName(),
|
||||
STE.getModuleVersion(),
|
||||
STE.getClassName(),
|
||||
STE.getMethodName(),
|
||||
STE.getFileName(),
|
||||
Integer.valueOf(STE.getLineNumber()),
|
||||
Boolean.valueOf(STE.isNativeMethod()),
|
||||
};
|
||||
|
||||
try {
|
||||
return new CompositeDataSupport(STE_COMPOSITE_TYPE,
|
||||
STE_ITEM_NAMES,
|
||||
steValue);
|
||||
} catch (OpenDataException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
static CompositeData makeStackTraceElementV5() throws OpenDataException {
|
||||
CompositeType steV5CType =
|
||||
new CompositeType("JDK 5 StackTraceElement",
|
||||
"CompositeType for JDK 5 StackTraceElement",
|
||||
STE_V5_ITEM_NAMES,
|
||||
STE_V5_ITEM_NAMES,
|
||||
STE_V5_ITEM_TYPES);
|
||||
|
||||
Object[] steV5Value = {
|
||||
STE.getClassName(),
|
||||
STE.getMethodName(),
|
||||
STE.getFileName(),
|
||||
Integer.valueOf(STE.getLineNumber()),
|
||||
Boolean.valueOf(STE.isNativeMethod()),
|
||||
};
|
||||
|
||||
return new CompositeDataSupport(steV5CType, STE_V5_ITEM_NAMES, steV5Value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a CompositeData of ThreadInfo without JDK 5 StackTraceElement
|
||||
*/
|
||||
static CompositeData makeThreadInfoWithV5StackTrace() throws OpenDataException {
|
||||
OpenType[] badTypes = ITEM_TYPES.clone();
|
||||
Object[] badValues = VALUES.clone();
|
||||
|
||||
CompositeData[] stackTrace = new CompositeData[1];
|
||||
stackTrace[0] = makeStackTraceElementV5();
|
||||
badTypes[STACK_TRACE] = new ArrayType(1, stackTrace[0].getCompositeType());
|
||||
badValues[STACK_TRACE] = stackTrace;
|
||||
CompositeType ct = new CompositeType("CompositeType",
|
||||
"ThreadInfo with JDK 5 StackTraceElement",
|
||||
ITEM_NAMES,
|
||||
ITEM_NAMES,
|
||||
badTypes);
|
||||
return new CompositeDataSupport(ct, ITEM_NAMES, badValues);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create MonitorInfo with JDK 5 StackTraceElement (i.e. JDK 6 MonitorInfo)
|
||||
* The value of "lockedStackFrame" attribute is null to ensure that
|
||||
* the validation is done.
|
||||
*/
|
||||
static CompositeData makeV6MonitorInfo() throws OpenDataException {
|
||||
CompositeData steV5 = makeStackTraceElementV5();
|
||||
|
||||
String[] names = MONITOR_INFO_COMPOSITE_TYPE.keySet().toArray(new String[0]);
|
||||
OpenType[] types = new OpenType[names.length];
|
||||
for (int i=0; i < names.length; i++) {
|
||||
String n = names[i];
|
||||
types[i] = "lockedStackFrame".equals(n)
|
||||
? steV5.getCompositeType()
|
||||
: MONITOR_INFO_COMPOSITE_TYPE.getType(n);
|
||||
}
|
||||
|
||||
CompositeType ctype =
|
||||
new CompositeType("JDK 6 MonitorInfo",
|
||||
"CompositeType for JDK 6 MonitorInfo",
|
||||
names,
|
||||
names,
|
||||
types);
|
||||
|
||||
Object[] values = {
|
||||
lockClassName,
|
||||
lockIdentityHashCode,
|
||||
-1,
|
||||
null
|
||||
};
|
||||
|
||||
return new CompositeDataSupport(ctype, names, values);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a CompositeData of ThreadInfo with incompatible MonitorInfo
|
||||
*/
|
||||
static CompositeData makeThreadInfoWithIncompatibleMonitorInfo() throws OpenDataException {
|
||||
OpenType[] badTypes = ITEM_TYPES.clone();
|
||||
Object[] badValues = VALUES.clone();
|
||||
|
||||
CompositeData[] lockedMonitors = new CompositeData[1];
|
||||
lockedMonitors[0] = makeV6MonitorInfo();
|
||||
badTypes[LOCKED_MONITORS] = new ArrayType(1, lockedMonitors[0].getCompositeType());
|
||||
badValues[LOCKED_MONITORS] = lockedMonitors;
|
||||
CompositeType ct = new CompositeType("CompositeType",
|
||||
"ThreadInfo with incompatible MonitorInfo",
|
||||
ITEM_NAMES,
|
||||
ITEM_NAMES,
|
||||
badTypes);
|
||||
return new CompositeDataSupport(ct, ITEM_NAMES, badValues);
|
||||
}
|
||||
|
||||
static CompositeData makeNewMonitorInfo() throws OpenDataException {
|
||||
String[] names = Stream.concat(MONITOR_INFO_COMPOSITE_TYPE.keySet().stream(),
|
||||
Stream.of("extra")).toArray(String[]::new);
|
||||
OpenType[] types = new OpenType[names.length];
|
||||
for (int i=0; i < names.length; i++) {
|
||||
String n = names[i];
|
||||
types[i] = "extra".equals(n)
|
||||
? SimpleType.STRING
|
||||
: MONITOR_INFO_COMPOSITE_TYPE.getType(n);
|
||||
}
|
||||
|
||||
CompositeType compositeType =
|
||||
new CompositeType("JDK X MonitorInfo",
|
||||
"CompositeType for JDK X MonitorInfo",
|
||||
names,
|
||||
names,
|
||||
types);
|
||||
|
||||
Object[] values = {
|
||||
lockClassName,
|
||||
lockIdentityHashCode,
|
||||
Integer.valueOf(1),
|
||||
makeStackTraceElement(),
|
||||
"extra"
|
||||
};
|
||||
|
||||
return new CompositeDataSupport(compositeType, names, values);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a CompositeData of ThreadInfo with a newer version of MonitorInfo
|
||||
*/
|
||||
static CompositeData makeThreadInfoWithNewMonitorInfo() throws OpenDataException {
|
||||
OpenType[] types = ITEM_TYPES.clone();
|
||||
Object[] badValues = VALUES.clone();
|
||||
|
||||
CompositeData[] lockedMonitors = new CompositeData[1];
|
||||
lockedMonitors[0] = makeNewMonitorInfo();
|
||||
types[LOCKED_MONITORS] = new ArrayType(1, lockedMonitors[0].getCompositeType());
|
||||
badValues[LOCKED_MONITORS] = lockedMonitors;
|
||||
CompositeType ct = new CompositeType("CompositeType",
|
||||
"ThreadInfo with JDK 5 MonitorInfo",
|
||||
ITEM_NAMES,
|
||||
ITEM_NAMES,
|
||||
types);
|
||||
return new CompositeDataSupport(ct, ITEM_NAMES, badValues);
|
||||
}
|
||||
|
||||
static CompositeData makeLockInfo() {
|
||||
Object[] lockInfoValue = {
|
||||
lockInfo.getClassName(),
|
||||
lockInfo.getIdentityHashCode(),
|
||||
};
|
||||
|
||||
try {
|
||||
return new CompositeDataSupport(LOCK_INFO_COMPOSITE_TYPE,
|
||||
LOCK_INFO_ITEM_NAMES,
|
||||
lockInfoValue);
|
||||
} catch (OpenDataException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
static CompositeData[] makeLockedSynchronizers() {
|
||||
CompositeData[] lockedSyncs = new CompositeData[1];
|
||||
lockedSyncs[0] = makeLockInfo();
|
||||
return lockedSyncs;
|
||||
}
|
||||
|
||||
static CompositeData[] makeLockedMonitors() {
|
||||
CompositeData[] lockedMonitorsCD = new CompositeData[1];
|
||||
|
||||
Object[] lockedMonitorsValue = {
|
||||
lockInfo.getClassName(),
|
||||
lockInfo.getIdentityHashCode(),
|
||||
makeStackTraceElement(),
|
||||
Integer.valueOf(1),
|
||||
};
|
||||
try {
|
||||
lockedMonitorsCD[0] =
|
||||
new CompositeDataSupport(MONITOR_INFO_COMPOSITE_TYPE,
|
||||
LOCKED_MONITORS_ITEM_NAMES,
|
||||
lockedMonitorsValue);
|
||||
} catch (OpenDataException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return lockedMonitorsCD;
|
||||
}
|
||||
|
||||
static final String[] V5_ITEM_NAMES = {
|
||||
"threadId",
|
||||
"threadName",
|
||||
"threadState",
|
||||
"blockedTime",
|
||||
"blockedCount",
|
||||
"waitedTime",
|
||||
"waitedCount",
|
||||
"lockName",
|
||||
"lockOwnerId",
|
||||
"lockOwnerName",
|
||||
"stackTrace",
|
||||
"suspended",
|
||||
"inNative",
|
||||
};
|
||||
|
||||
static final String[] V6_ITEM_NAMES = {
|
||||
"lockInfo",
|
||||
"lockedMonitors",
|
||||
"lockedSynchronizers",
|
||||
};
|
||||
|
||||
static final String[] V9_ITEM_NAMES = {
|
||||
"daemon",
|
||||
"priority",
|
||||
};
|
||||
|
||||
static final OpenType[] V5_ITEM_TYPES = {
|
||||
SimpleType.LONG,
|
||||
SimpleType.STRING,
|
||||
SimpleType.STRING,
|
||||
SimpleType.LONG,
|
||||
SimpleType.LONG,
|
||||
SimpleType.LONG,
|
||||
SimpleType.LONG,
|
||||
SimpleType.STRING,
|
||||
SimpleType.LONG,
|
||||
SimpleType.STRING,
|
||||
STE_ARRAY_COMPOSITE_TYPE,
|
||||
SimpleType.BOOLEAN,
|
||||
SimpleType.BOOLEAN,
|
||||
};
|
||||
|
||||
static final OpenType[] V6_ITEM_TYPES = {
|
||||
LOCK_INFO_COMPOSITE_TYPE,
|
||||
MONITOR_INFO_ARRAY_COMPOSITE_TYPE,
|
||||
LOCK_INFO_ARRAY_COMPOSITE_TYPE,
|
||||
};
|
||||
|
||||
static final OpenType[] V9_ITEM_TYPES = {
|
||||
SimpleType.BOOLEAN,
|
||||
SimpleType.INTEGER,
|
||||
};
|
||||
|
||||
static final String[] STE_ITEM_NAMES = {
|
||||
"classLoaderName",
|
||||
"moduleName",
|
||||
"moduleVersion",
|
||||
"className",
|
||||
"methodName",
|
||||
"fileName",
|
||||
"lineNumber",
|
||||
"nativeMethod",
|
||||
};
|
||||
|
||||
static final String[] STE_V5_ITEM_NAMES = Arrays.copyOfRange(STE_ITEM_NAMES, 3, 8);
|
||||
|
||||
static final OpenType[] STE_V5_ITEM_TYPES = {
|
||||
SimpleType.STRING,
|
||||
SimpleType.STRING,
|
||||
SimpleType.STRING,
|
||||
SimpleType.INTEGER,
|
||||
SimpleType.BOOLEAN
|
||||
};
|
||||
|
||||
static final String[] LOCK_INFO_ITEM_NAMES = {
|
||||
"className",
|
||||
"identityHashCode",
|
||||
};
|
||||
|
||||
static final String[] LOCKED_MONITORS_ITEM_NAMES = {
|
||||
LOCK_INFO_ITEM_NAMES[0],
|
||||
LOCK_INFO_ITEM_NAMES[1],
|
||||
"lockedStackFrame",
|
||||
"lockedStackDepth",
|
||||
};
|
||||
|
||||
static final Object[] V5_VALUES = {
|
||||
Long.valueOf(100),
|
||||
"FooThread",
|
||||
"RUNNABLE",
|
||||
Long.valueOf(200),
|
||||
Long.valueOf(10),
|
||||
Long.valueOf(300),
|
||||
Long.valueOf(20),
|
||||
lockName,
|
||||
Long.valueOf(99),
|
||||
"BarThread",
|
||||
new CompositeData[] { makeStackTraceElement() },
|
||||
Boolean.valueOf(false),
|
||||
Boolean.valueOf(false),
|
||||
};
|
||||
|
||||
static final Object[] V6_VALUES = {
|
||||
makeLockInfo(),
|
||||
makeLockedMonitors(),
|
||||
makeLockedSynchronizers(),
|
||||
};
|
||||
|
||||
static final Object[] V9_VALUES = {
|
||||
Boolean.valueOf(true),
|
||||
Thread.NORM_PRIORITY,
|
||||
};
|
||||
|
||||
static final String[] ITEM_NAMES =
|
||||
concat(V5_ITEM_NAMES, V6_ITEM_NAMES, V9_ITEM_NAMES).toArray(String[]::new);
|
||||
|
||||
static final OpenType[] ITEM_TYPES =
|
||||
concat(V5_ITEM_TYPES, V6_ITEM_TYPES, V9_ITEM_TYPES).toArray(OpenType[]::new);
|
||||
|
||||
static final Object[] VALUES =
|
||||
concat(V5_VALUES, V6_VALUES, V9_VALUES).toArray(Object[]::new);
|
||||
|
||||
static <T> Stream<T> concat(T[]... streams) {
|
||||
return Stream.of(streams).flatMap(a -> Arrays.stream(a));
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue