-
Bug
-
Resolution: Fixed
-
P4
-
9.0.4
-
None
ThreadInfo.from(CompositeData) returns a new ThreadInfo, choosing the fields to instantiate based on whether the CompositeData contains the fields in a particular JDK release. So, for example, if the CompositeData contains the fields for JDK 6, the fields for JDK 6 will be instantiated. Here is the relevant code:
// 6.0 attributes
if (ticd.hasV6()) {
lock = ticd.lockInfo();
lockedMonitors = ticd.lockedMonitors();
lockedSynchronizers = ticd.lockedSynchronizers();
} else {
// lockInfo is a new attribute added in 1.6 ThreadInfo
// If cd is a 5.0 version, construct the LockInfo object
// from the lockName value.
if (lockName != null) {
String result[] = lockName.split("@");
if (result.length == 2) {
int identityHashCode = Integer.parseInt(result[1], 16);
lock = new LockInfo(result[0], identityHashCode);
} else {
assert result.length == 2;
lock = null;
}
} else {
lock = null;
}
lockedMonitors = EMPTY_MONITORS;
lockedSynchronizers = EMPTY_SYNCS;
}
// 9.0 attributes
if (ticd.isCurrentVersion()) {
daemon = ticd.isDaemon();
priority = ticd.getPriority();
} else {
// Not ideal, but unclear what else we can do.
daemon = false;
priority = Thread.NORM_PRIORITY;
}
The problem with this is that ticd.isCurrentVersion tests to make sure that *all* of the fields are present. Two of the fields - lockedMonitors and lockedSynchronizers - are spec'd to be optional. If the CompositeData is missing those two fields, the daemon and priority fields will not get set.
There is a test for this use case, but is assigns false to daemon and Thread.NORM_PRIORITY to priority, so the failure wasn't detected.
// 6.0 attributes
if (ticd.hasV6()) {
lock = ticd.lockInfo();
lockedMonitors = ticd.lockedMonitors();
lockedSynchronizers = ticd.lockedSynchronizers();
} else {
// lockInfo is a new attribute added in 1.6 ThreadInfo
// If cd is a 5.0 version, construct the LockInfo object
// from the lockName value.
if (lockName != null) {
String result[] = lockName.split("@");
if (result.length == 2) {
int identityHashCode = Integer.parseInt(result[1], 16);
lock = new LockInfo(result[0], identityHashCode);
} else {
assert result.length == 2;
lock = null;
}
} else {
lock = null;
}
lockedMonitors = EMPTY_MONITORS;
lockedSynchronizers = EMPTY_SYNCS;
}
// 9.0 attributes
if (ticd.isCurrentVersion()) {
daemon = ticd.isDaemon();
priority = ticd.getPriority();
} else {
// Not ideal, but unclear what else we can do.
daemon = false;
priority = Thread.NORM_PRIORITY;
}
The problem with this is that ticd.isCurrentVersion tests to make sure that *all* of the fields are present. Two of the fields - lockedMonitors and lockedSynchronizers - are spec'd to be optional. If the CompositeData is missing those two fields, the daemon and priority fields will not get set.
There is a test for this use case, but is assigns false to daemon and Thread.NORM_PRIORITY to priority, so the failure wasn't detected.
- csr for
-
JDK-8198732 ThreadInfo.from(CompositeData) does not throw IAE when the given CompositeData with missing attributes
-
- Closed
-
- relates to
-
JDK-8212197 OpenDataException thrown when constructing CompositeData for StackTraceElement
-
- Closed
-
-
JDK-8212795 ThreadInfoCompositeData.toCompositeData fails to map ThreadInfo to CompositeData
-
- Closed
-